Using Recursions and Closures

  • Note: Use setTimeout to avoid Error Call Stack Size Exceeded
  • JavaScript Code:
cPanel.scheduleMapsSliderStatus = function (rc, func) {
    var runCount = rc;
    var funcName = 'scheduleMapsSliderStatus()';
    var logHeader = myControlPanel.getLogHeaderCF(funcName, func);

    var slideShowStatusSummaryField =  myObjects.getPanel("slideShowStatusSummaryField");
    var bgColor = slideShowStatusSummaryField.css('background-color');
    var fgColor =  slideShowStatusSummaryField.css('color');
    
    function MapsSliderStatusClosure() {
        var mesgFlag = runCount % 2;
        var panelMode = myControlPanel.getPanelMode(funcName);
        var slideShowStatusSummaryField = null;
        if (mesgFlag === 0) {
            updateSliderStatus("Click on PLAY button to start Animation! ");
                // Need to reread slideShowStatusSummaryField Objects as this is recreated by  updateSliderStatus()
            slideShowStatusSummaryField =  myObjects.getPanel("slideShowStatusSummaryField");
            slideShowStatusSummaryField.css('background-color', bgColor);

        } else {
            updateSliderStatus("Click on GREEN Marker to start Slideshow !");
                // Need to reread slideShowStatusSummaryField Objects as this is recreated by  updateSliderStatus()
            slideShowStatusSummaryField =  myObjects.getPanel("slideShowStatusSummaryField");
            slideShowStatusSummaryField.css('background-color', 'green');
        }
        if (runCount === 10 ) {   // run this Animation ONLY 10x
            return;
         }
        if (panelMode === "maps") { // Don't schedule again if panelMode !='maps'
            runCount++;
            setTimeout(MapsSliderStatusClosure, 2000, runCount, funcName)
        }
    };
    MapsSliderStatusClosure();   // Just all the closure function a first time
};

 

 

Avoid Maximum call stack size exceeded in JavaScript

Overview

  • Error Maximum call stack size exceeded  is raised when calling a recursive function in a  loop
  •  This is expected – as every Javascript Engine has a maximum Call Stack Range

Failing Javascript Code

function errorFunc(rc) {
    var runCount = rc;
  var maxCount = 100000;
  if ( (rc % 5000) === 0 ) {
    logMessage("errorFunc():: Recursion Count:  " + runCount );
  } 
  runCount++;
  if (runCount >= maxCount ) {
      logMessage("errorFunc() reached MAX recursion Count :  " + runCount );
    return;
  }
  try {
      errorFunc(runCount);
      } catch (e ) {
        if ( e instanceof RangeError) {
            logMessage("errorFunc():: " + e +  ": " + runCount );
        }
      }
};

  • Output

recursionOK

Fixed Code be using setTimeout() function

  • Workraound : use setTimeout() function
  • setTimeout() function always creates a Top Level Function
function     workingFunc(rc) {
    // logMessage("workingFunc()");
  var runCount = rc;
  var maxCount = 100000;
  if ( (rc % 20000) === 0 ) {
    logMessage("workingFunc():: Recursion Count:  " + runCount );
  } 
  runCount++;
  if (runCount >= maxCount ) {
      logMessage("workingFunc() reached MAX recursion Count :  " + runCount );
    return;
  }
 
  try {
      setTimeout( workingFunc, 0, runCount);
      } catch (e ) {
        if ( e instanceof RangeError) {
            logMessage("workingFunc():: " + e +  ": " + runCount );
        }
      }
  };
  • Output of fixed CoderecursionOK
  • Note: The setTimeout() Workaorund is very slow

References

 

Calling JavaScript function for a top Level Object by using a String

JavaScript Code

var myPanel = null;              /* Our object */
function testFunctions(func) {
    logStatus("Function " + func + " Active !");
    myPanel = createPanel();
    var info = "Calling ANONYMOUS Function" ;
    myPanel.testfunc(info);
    info = "Calling NAMED     Function" ;
    myPanel.testfunc2(info);
    info = "Calling ANONYMOUS Function VIA String" ;
    myPanel.invokeFuncByString(myPanel, "testfunc",info);
    info = "Calling NAMED     Function VIA String" ;
    myPanel.invokeFuncByString(myPanel, "testfunc2",info);
}

function createPanel(vSingleClickInProgess, vClickTimeout) {
    var panel = Object.create(Object.prototype, {
        objectName: {value: "panel", writable: true}      /* just provide a name for our object */
    });
    panel.testfunc  = function (info) {
        logStatus ("__ " + info);
    };
    panel.testfunc2  = function (info) {
        logStatus ("__ " + info);
    };
    panel.invokeFuncByString = function(obj,funcName,info) {
        var fnString= funcName;
        var fn = obj[fnString];
                // is object a function?
        if (typeof fn === "function")
            fn(info + " - ObjectName: " +  obj.objectName  + " - functionName: " + funcName);
        else {
            logErrorT(logHeader, "__ fn IS NOT A Function - : fnString " + fnString + " type: " + typeof fn )
        }
    }
    return panel;
};

Output

17:05:12:740 STATUS::__ Calling ANONYMOUS Function
17:05:12:740 STATUS::__ Calling NAMED     Function
17:05:12:741 STATUS::__ Calling ANONYMOUS Function VIA String - ObjectName: panel - functionName: testfunc
17:05:12:742 STATUS::__ Calling NAMED     Function VIA String - ObjectName: panel - functionName: testfunc2

References

PlugINs and Editor Setting for WordPress Projects

Currently I’m using 2 PlugINs and I’ve disabled WYSIWYG Editor for my WordPress Projects

  • Insert_PHP [ used to run PHP code ]
  • Raw HTML [ need to be version 1.5 – 1.4 converts HTML during saving the Code
  • Disable Visual Editing first User -> Profil -> Disable WYSIWYG Editor

Note :  You CAN’T run [insert_php]…[/insert_php] Block inside a [raw] .. [/raw] Block
Raw Html need to be at version 1.5 !


Insert_PHP Plugin: 
Descriptiuon: 
   Run PHP code inserted into WordPress posts and pages.
  
- In the sample below we use Insert_PHP Plugin to call get_stylesheet_directory_uri() 
- get_stylesheet_directory is used by Child Themes [ here we reference an Image location]

Sample:
<td class="firstImageAbu" rowspan="5"><img src=[insert_php]echo get_stylesheet_directory_uri()."/images/htmlImages/abu1.jpg 
   alt='Sponsoren FCW' width=215 />";[/insert_php]</td>  
    

Raw HTML PlugIN
Descripton:
    Lets you enter any HTML/JS/CSS in your posts without WP changing it, as well as disable 
    automatic formatting on a per-post basis. Usage: Wrap your code in [raw]...[/raw] tags. 
    To avoid problems, only edit posts that contain raw code in HTML mode. Upgrade to Pro 
    to be able to use Visual editor on the same posts without it messing up the code.

Note: Used that PlugIN for a ControlPanel. Without that code the Buttons get strange aligned when 
using <CR> to beautify your Code !

Sample:
[raw]
<div id="AbuControlPanel">
  <input id="infoButton" class="mediumButton" type="submit" value="" />
  <input id="homeButton" class="mediumButton" type="submit" value="" />
  <div id="AbuButtonGroup" class="button-group">
    <input id="stopButton" class="mediumButton" type="submit" value="" />
    <input id="playButton" class="mediumButton" type="submit" value="" />
    <input id="prevButton" class="mediumButton" type="submit" value="" />
    <input id="nextButton" class="mediumButton" type="submit" value="" />
  </div>
</div>
[/raw]

WordPress: Using Duplicator PlugIN

Step 1:  Install WP Plugin: Duplicator 1.1.8

  • Nothing to add here just install the WordPress Plugin

 

Step2 : Create a Package and upload Installer.php and archive to your local host

  • Duplicator -> Package -> Create New -> Next

Create a New Package

Duplicator1

  • You can ignore the Database Warning [ see video below ]

Lets have a closer look on the PHP errors

Duplicator2

  • Ignoring that Warning for now – but notice that I’m not able to restore that package on the original Server again —>  Not a good  situation but lets move forward 
  • Check:  

 

BUILD the package

  • Finally if we don’t get a timeout you will see the following message .

Duplicator3

  • Click on both buttons to download the both files
  •  Note : Even you may get a Timeout the action may still run successfully to the end

 

Step 3 Create a MySql Database via phpAdmin

Duplicator4

 

Step 4:  Deploy the WordPress Backup to our local XAMPP webserver

  • Verify both files are under the proper newly created directory [ xampp\htdocs ]

Duplicator5

 

Invoke installer.php and test your MySQL connection

Duplicator6

  • Testing MySql Database worked fine

 

Update Files and Database

Duplicator7

 

Apply Final Steps

  • Test Site
  • Security Cleanup

Duplicator8

 

Testing the duplicated Website

Duplicator9

  • As you see the Website Duplication to our localhost works!
  • Now you can remove the Duplicator Files by running Security Cleanup

Reference

 

Google Maps Markers disappear after multiple fitBounds() calls

Problem Description

  • You have mulitple fitBounds() calls to display your Google Map
  • After some calls  your draggable Markers disappear from your Map
  • If you slightly move the Map the Markers get displayed again
  • Very likely you hit Googe Maps Bug 5176

Workaround 1

  • Create your Maps Marker with draggable set to false
var tMarker = new google.maps.Marker({
    position: markerPos,
    draggable: false, 

Workaround 2

  • In case your need a draggable marker call map.panBy(0,0) to fix the problem
  • Flow
    • fitBounds() triggers the center_changed event
    • Within this event call panBy() without moving the map at all
google.maps.event.addListenerOnce(gMap, 'center_changed', function() {
    var gMap = myControlPanel.getMap();  // Die and give up if gMap is null
    gMap.panBy(0,0);
});

gMap.fitBounds(bounds);

JavaScript: Prototypal Object Inheritance

Overview and Key Facts

  • According to Douglas Crockford and  Eric Elliot Prototypal Inheritance should be preferred over Classical  Inheritance
  • Objects in Javascript inherit their Properties/Methods from what is called a prototype instead of a class definition
  • Prototypes are standard objects themselves and builds up a Prototype Chain      
  • The Prototype Chain top level object is Object.prototype and delegates methods like toString() to each JavaScriot Object with a working Prototype Chain
  • Same prototype means same object instance
  • Every JavaScript Object should get its behavior from functions in its prototype
  • ECMAScript 5 introduced a new method: Object.create() which simplifies creating a Prototype Chain without Douglas Crockfords “WorkAround” simulating Object.create()

 Inherit from a Object Literal using Object.create

  • Object.create(Mammal, …  uses the Mammel Object  created from am  Object Literal  as its Prototype
  • MammelObj inherits Properties type and objectName from Mammel
  • MammelObj inherits Function getDetails from Mammel
  • MammelObj adds _objectName Data Descriptor
  • MammelObj adds an Accessor Descriptor objectName which works on _objectName property
JavaScript Code:

var Mammal = {
    type: 'Mammal',
    objectName : 'Mammal BASE Object',
    getDetails: function () {
        return("Type: " + this.type + " - ObjectName:  "  + this.objectName);
    }

};

function runObjectTest9() {
    logMessage('--- Prototypal Inheritance via Object.create [ for details check JavaScript console ] ---');
    logMessage("Global Mammal Object created via String Literals:: type: " + Mammal.type + " - getDetails(): " + Mammal.getDetails());
    var MammalObj = Object.create(Mammal, {
        _objectName : { value: 'INITIAL MammelObj', writable: true},
        objectName: {
            configurable: true,
            get: function getObjectName () {
                logMessage('[MammalObj objectName get]:: ' + this._objectName );
                return this._objectName;
            },
            set: function setObjectName (value) {
                oldVal = this._objectName;
                this._objectName = value;
                logMessage("[MammalObj objectName set]:: NEW Value: " + this._objectName + " - Old Value: " + oldVal );
            }
         }
    });

    logMessage('[MammalObj.objectName]:: ' + MammalObj.objectName);
    MammalObj.objectName = "MammalObj";
    MammalObj.isWalking = false;
    logMessage("[MammalObj.getDetails()]:: " + MammalObj.getDetails());
    logMessage("[MammalObj.type]:: " + MammalObj.type);
    checkProperties(MammalObj);
    logMessage('------------------------------------------------------------------------');
}

Output: 
--- Prototypal Inheritance via Object.create [ for details check JavaScript console ] ---
Global Mammal Object created via String Literals:: type: Mammal - getDetails(): Type: Mammal - ObjectName:  Mammal BASE Object
[MammalObj objectName get]:: INITIAL MammelObj
[MammalObj.objectName]:: INITIAL MammelObj
[MammalObj objectName set]:: NEW Value: MammalObj - Old Value: INITIAL MammelObj
[MammalObj objectName get]:: MammalObj
[MammalObj.getDetails()]:: Type: Mammal - ObjectName:  MammalObj
[MammalObj.type]:: Mammal
[MammalObj objectName get]:: MammalObj
  • Output and Code for checkProperties(MammalObj) can be found here 

What happens with undefined properties and Methods  ?

  • Note we are uisng the above Objects Mammal and MammalObj
  • Referencing a NON existent function raises an Error:  TypError xxx.xxx  is not a function
  • Referencing a a NON existent property returns undefined
JavaScript Code:

logMessage('--- Testing TypeError: Object.function  is not a function ---');
try {
    logMessage("MammalObj.getAge():: " + MammalObj.getAge());
}   catch (e) {
    logMessage("FATAL ERROR:: Catching Exception running MammalObj.getAge() :: " + e);
}
logMessage("MammalObj.age :: " + MammalObj.age);
checkProperties(MammalObj);
logMessage('------------------------------------------------------------------------');

Output: 
--- Testing TypeError: Object.function  is not a function ---
FATAL ERROR:: Catching Exception running MammalObj.getAge() :: TypeError: MammalObj.getAge is not a function
MammalObj.age :: undefined
[MammalObj objectName get]:: MammalObj

 

Overwrite Object Methods

  • Note we still use  the object definition from our first sample for Mammal and MammalObj
JavaScript Code:

logMessage('--- Testing Overwrite Methodes ---');
var CatObj =  Object.create(MammalObj);
CatObj.legs =4;
CatObj.canWalk = function ()  {
    return("I've " + this.legs + " legs and can walk" );
};
CatObj.getDetails = function ()  {
    var myType = this.type;
    var myLegs = this.legs;
    return("[CatObj] - Hi, I'm a " + myType + " and I've " + myLegs + " legs and can walk" );
};
logMessage("catObj.canWalk():: " + CatObj.canWalk());
logMessage("catObj.getDetails():: " + CatObj.getDetails());
checkProperties(CatObj);
logMessage('------------------------------------------------------------------------');

Output: 
--- Testing Overwrite Methodes ---
catObj.canWalk():: I've 4 legs and can walk
catObj.getDetails():: [CatObj] - Hi, I'm a Mammal and I've 4 legs and can walk
[MammalObj objectName get]:: MammalObj


 Stripped Output from checkProperties(CatObj);

--- Detailed ProtoType Function walking down the Prototype Chain - Level:  1---
    ...
--- Detailed ProtoType Function walking down the Prototype Chain - Level:  2---
    ...
--- Detailed ProtoType Function walking down the Prototype Chain - Level:  3---
    ...
      
       [Mammal BASE Object, level:3][Found a FUNCTION] - Function Name: getDetails - Type: function - getPrototypeOf: function () {} - Constructor: function Function() { [native code] }
       [Mammal BASE Object, level:3] - Data Descriptor: Configurable: true - Enumerable: true - Writable: true - Value: function () {
        return("Type: " + this.type + " - ObjectName:  "  + this.objectName);
    }
   
   [CatObj, level:1][Found a FUNCTION] - Function Name: getDetails - Type: function - getPrototypeOf: function () {} - Constructor: function Function() { [native code] }
   [CatObj, level:1] - Data Descriptor: Configurable: true - Enumerable: true - Writable: true - Value: function ()  {
        var myType = this.type;
        var myLegs = this.legs;
        return("[CatObj] - Hi, I'm a " + myType + " and I've " + myLegs + " legs and can walk" );
    } 
  • There is a getDetails methode implemented by CatObj and Mammal BASE Object
  • The first method from catObj [ CatObj, level 1 ] is picked up when walking down the Prototype Chain

Modifying an underlying Object down in the Prototype Chain

  • Let’s create 2 cats named Fini and Felicitas based on CatObj
  • Change the type to Fish and modify their number of legs to 2
JavaScript Code : 

var CatObj =  Object.create(MammalObj);
CatObj.legs =4;
CatObj.objectName = 'CatObj';
CatObj.type = 'CAT';
CatObj.canWalk = function ()  {
    return("I've " + this.legs + " legs and can walk" );
};
CatObj.getDetails = function ()  {
    return("[CatObj] - Hi, I'm a " + this.type + " and I've " +  this.legs + " legs and can walk" );
};
logMessage("CatObj.getDetails():: " + CatObj.getDetails());
checkProperties(CatObj);
logMessage('------------------------------------------------------------------------');

logMessage('--- Modifying an underlying Object down in the Prototype Chain ----');
var felicitas =  Object.create(CatObj);
felicitas.age = 11;
felicitas.name = 'Felicitas';
logMessage("felicitas.getDetails():: " + felicitas.getDetails());

var fini = Object.create(CatObj);
fini.age = 9;
fini.name = 'Fini';
logMessage("fini.getDetails():: " + fini.getDetails());

logMessage("  ------ Lets modify all Cats to become a FISH type with 2 Legs ! ----- ")
CatObj.type = 'FISH';
CatObj.legs = 2;

logMessage("felicitas.getDetails() after morphing  Cats to a Fish :: " + felicitas.getDetails());
logMessage("fini.getDetails() after morphing Cats to a Fish:: " + fini.getDetails());
logMessage('------------------------------------------------------------------------');
 
Output : 
--- Modifying an underlying Object down in the Prototype Chain ----
felicitas.getDetails():: [CatObj] - Hi, I'm a CAT and I've 4 legs and can walk
fini.getDetails():: [CatObj] - Hi, I'm a CAT and I've 4 legs and can walk
  ------ Lets modify all Cats to become a FISH type with 2 Legs ! ----- 
felicitas.getDetails() after morphing  Cats to a Fish :: [CatObj] - Hi, I'm a FISH and I've 2 legs and can walk
fini.getDetails() after morphing Cats to a Fish:: [CatObj] - Hi, I'm a FISH and I've 2 legs and can walk

 

Directly Calling Methods from a Prototype Object

  • Calling Methods from a Prototype Object may return undefined
  • You should use call() or apply() to provide the correct THIS context [ felicitat Object ]
  • felicitas.getDetailsFromCat() fails because THIS context is pointing to the CatObj Object which doesn’t have properties this.name and  this.age
JavaScript Code:

    logMessage('--- Directly Calling Methods from a Prototype Object---');
    CatObj.type = 'CAT';
    CatObj.legs = 4;
    CatObj.getDetails = function ()  {
        return("Hi, my name is " +  this.name + " and I'm " + this.age + " years old. I'm a " + this.type
        + " and I've " + this.legs + " legs and can walk" );
    };
    var felicitas =  Object.create(CatObj);
    felicitas.age = 11;
    felicitas.name = 'Felicitas';
    felicitas.fObjectName = 'felicitas';

    felicitas.getDetailsFromCat = function () {
        CatObj.getDetails();     // this context is pointing to CatObj having NO this.name and this.age property
    };
    logMessage("felicitas.getDetailsFromCat() :: " +  CatObj.getDetails() );

    felicitas.getDetailsFromCat2 = function () {
        // this context now pointing to felicitas having this.name and this.age property
        logMessage("felicitas.getDetailsFromCat2() :: " +  CatObj.getDetails.call(this) );
    };
    felicitas.getDetailsFromCat2();
    logMessage("felicitas.getDetails():: " + felicitas.getDetails());
    logMessage('------------------------------------------------------------------------');

Output:  
  --- Directly Calling Methods from a Prototype Object---
felicitas.getDetailsFromCat() :: Hi, my name is undefined and I'm undefined years old. I'm a CAT and I've 4 legs and can walk
felicitas.getDetailsFromCat2() :: Hi, my name is Felicitas and I'm 11 years old. I'm a CAT and I've 4 legs and can walk
felicitas.getDetails():: Hi, my name is Felicitas and I'm 11 years old. I'm a CAT and I've 4 legs and can walk


 

References

Object Reflection in JavaScript by Sample

Overview

  • Javascrript has an API to use Reflection similar to  JAVA
  • You can follow the Prototypal Chain to figure out the Object Properties and Functions
  • Of course you can use Chrome Dev Tools  but if you need a programatically approach continue reading
  • The code may not be prefect - any comments/improvements are appreciated
  • checkProperties(MammalObj) is used to walk down the Prototype Chain

JavaScript Code for Object inheritance

var Mammal = {
    type: 'Mammal',
    objectName : 'Mammal BASE Object',
    getDetails: function () {
        return("Type: " + this.type + " - ObjectName:  "  + this.objectName);
    }
};

function runObjectTest9() {
    logMessage('--- Prototypal Inheritance via Object.create [ for details check JavaScript console ] ---');
    logMessage("Global Mammal Object created via String Literals:: type: " + Mammal.type + " - getDetails(): " + Mammal.getDetails());
    var MammalObj = Object.create(Mammal, {
        _objectName : { value: 'INITIAL MammelObj', writable: true},
        objectName: {
            configurable: true,
            get: function getObjectName () {
                logMessage('[MammalObj objectName get]:: ' + this._objectName );
                return this._objectName;
            },
            set: function setObjectName (value) {
                oldVal = this._objectName;
                this._objectName = value;
                logMessage("[MammalObj objectName set]:: NEW Value: " + this._objectName + " - Old Value: " + oldVal );
            }
         }
    });

    logMessage('[MammalObj.objectName]:: ' + MammalObj.objectName);
    MammalObj.objectName = "MammalObj";
    MammalObj.isWalking = false;
    logMessage("[MammalObj.getDetails()]:: " + MammalObj.getDetails());
    logMessage("[MammalObj.type]:: " + MammalObj.type);
    checkProperties(MammalObj);
    logMessage('------------------------------------------------------------------------');
}
Output: 
--- Prototypal Inheritance via Object.create [ for details check JavaScript console ] ---
Global Mammal Object created via String Literals:: type: Mammal - getDetails(): Type: Mammal - ObjectName:  Mammal BASE Object
[MammalObj objectName get]:: INITIAL MammelObj
[MammalObj.objectName]:: INITIAL MammelObj
[MammalObj objectName set]:: NEW Value: MammalObj - Old Value: INITIAL MammelObj
[MammalObj objectName get]:: MammalObj
[MammalObj.getDetails()]:: Type: Mammal - ObjectName:  MammalObj
[MammalObj.type]:: Mammal
[MammalObj objectName get]:: MammalObj

 

Implementation of Reflection Code

function checkProperties(o) {
    level =1 ;
    checkPropertiesPrototype(o,level);
}
var endOfPrototypeChainReached = false;

function checkPropertiesPrototype(oProto,level) {
        // limit the Prototype Chain depth
    if ( level === 10) {
        logMessage("Prototype Chain > 10 : termination - Check for CodeBUGS !");
        return;
    }
    /*
     * Abort walking down the Property Chain action when we reach the  Object.prototype object
     * Note:  Object.getPrototypeOf returns null when we reach the TOP Level Object.prototype object
     */
    var o = oProto;
    var prefix = getPrefix(level*2) + " [" + o.objectName + ", level:" + level + "]";
    var oProtoNext = Object.getPrototypeOf(oProto); 
    if ( !oProtoNext) {
            // o.objectName is undefined for  Object.prototype  - Fix this
        prefix = getPrefix(level*2) + " [Object.prototype, level:" + level + "]";
           // logMessage(prefix + " End of protoype Chain reached: Level: " + level);
           // Mark that we have reached the END of our Prototype Chain
        endOfPrototypeChainReached = true;
        return;
       }     
    logMessage("--- Detailed ProtoType Function walking down the Prototype Chain - Level:  " + level + '---');
    Object.getOwnPropertyNames(o).forEach(function(val) 
    {
        var objRef =  o[val];
        var foundIt = "";
        var p =   Object.getPrototypeOf(objRef);
        /*
            JavaScript has 5 primitives: Number, String, Boolean ,Undefined, Null [  Anything else is considered an object ]
            Object.getPrototypeOf(objRef) returns NULL for Primitives like  Number, String, Boolean ,Undefined, Null
        */
        var foundFunc = false;
        if ( typeof(objRef) === 'function') {
            foundIt = "[Found a FUNCTION]";
            foundFunc = true;
        }
        else if ( typeof(objRef) === 'object') {
            foundIt = "[Found an OBJECT]";
        }

        /*
        Object Properties:
            Data Descriptor     : configurable, enumerable, value, writable
            Accessor descriptor : configurable, enumerable, set, get
        */
        var propRes = "Oops- check getOwnPropertyDescriptor Code";
        d = Object.getOwnPropertyDescriptor(o, val);
        if ( d ) {
            if ( !d.get  || !d.set ) {
                propRes = " - Data Descriptor: Configurable: " +  d.configurable + " - Enumerable: " + d.enumerable +
                    " - Writable: " + d.writable + " - Value: " + d.value;
            }
            else {
                propRes = " - Accessor Descriptor: Configurable " +  d.configurable + " - Enumerable " + d.enumerable +
                    " - Set: " + d.set + " - Get: " +  d.get;
            }
        }
        if (foundFunc) {
            logMessage(prefix + foundIt + " - Function Name: " + val + " - Type: " + typeof(objRef)
                + " - getPrototypeOf: " + p  + " - Constructor: " + objRef.constructor + "\n" + prefix +  propRes);
        }
        else {
            logMessage(prefix + foundIt + " - Property Name: " + val + " - Value: " + objRef + " - Type: " + typeof(objRef)
                + " - getPrototypeOf: " + p  + " - Constructor: " + objRef.constructor + "\n" + prefix +  propRes);
        }
        
        var oProto = Object.getPrototypeOf(o);
            // Dont walk down the Prototype Chain more than ONCE
        if ( !endOfPrototypeChainReached)
            checkPropertiesPrototype(oProto,level+1);
    });
   level++;
}

function getPrefix(len)
{
var eStr = '';
while( eStr.length < len )
    {
        eStr = eStr + ' ';
    }        
return eStr;
}

 

Output from Reflection Script

--- Detailed ProtoType Function walking down the Prototype Chain - Level:  1---

   [MammalObj, level:1] - Property Name: _objectName - Value: MammalObj - Type: string - getPrototypeOf:  - Constructor: function String() { [native code] }
   [MammalObj, level:1] - Data Descriptor.: Configurable: false - Enumerable: false - Writable: true - Value: MammalObj

--- Detailed ProtoType Function walking down the Prototype Chain - Level:  2---

     [Mammal BASE Object, level:2] - Property Name: type - Value: Mammal - Type: string - getPrototypeOf:  - Constructor: function String() { [native code] }
     [Mammal BASE Object, level:2] - Data Descriptor.: Configurable: true - Enumerable: true - Writable: true - Value: Mammal

     [Mammal BASE Object, level:2] - Property Name: objectName - Value: Mammal BASE Object - Type: string - getPrototypeOf:  - Constructor: function String() { [native code] }
     [Mammal BASE Object, level:2] - Data Descriptor.: Configurable: true - Enumerable: true - Writable: true - Value: Mammal BASE Object

     [Mammal BASE Object, level:2][Found a FUNCTION] - Function Name: getDetails - Type: function - getPrototypeOf: function () {} - Constructor: function Function() { [native code] }
     [Mammal BASE Object, level:2] - Data Descriptor.: Configurable: true - Enumerable: true - Writable: true - Value: function () {
                                     return("Type: " + this.type + " - ObjectName:  "  + this.objectName);  }
                                     
   [MammalObj, level:1] - Property Name: objectName - Value: MammalObj - Type: string - getPrototypeOf:  - Constructor: function String() { [native code] }
   [MammalObj, level:1] - Accessor Descriptor: Configurable true - Enumerable false - Set: function setObjectName(value) {
                oldVal = this._objectName;
                this._objectName = value;
                logMessage("[MammalObj objectName set]:: NEW Value: " + this._objectName + " - Old Value: " + oldVal );
            } - Get: function getObjectName() {
                logMessage('[MammalObj objectName get]:: ' + this._objectName );
                return this._objectName;
            }
   [MammalObj, level:1] - Property Name: isWalking - Value: false - Type: boolean - getPrototypeOf: false - Constructor: function Boolean() { [native code] }
   [MammalObj, level:1] - Data Descriptor.: Configurable: true - Enumerable: true - Writable: true - Value: false