src/pyjamas.js
/**
     * Decodes an object to become an instance of the given constructor
     *
     * @param constructor   {function}  Object constructor
     * @param target        {object}    Raw object that populates a new instance
     * @param [defers]      {Array}     Constructors to defer execution
     *
     * @return {object} New instance of the constructor
     * @private
     */
Decodes an object to become an instance of the given constructor
@param constructor   {function}  Object constructor
@param target        {object}    Raw object that populates a new instance
@param [defers]      {Array}     Constructors to defer execution

@return {object} New instance of the constructor
@private
Decodes an object to become an instance of the given constructor @param constructor { function } Object constructor @param target { object } Raw object that populates a new instance @param [ defers ] { Array } Constructors to defer execution @return { object } New instance of the constructor @private
function decode (constructor, target, defers) {
        var key, instance, pjs;
        pjs      = PyjamasDB.fetch(constructor) || {};
        defers   = (pjs.defers || []).concat(defers || []);
        instance = construct(constructor, target, defers);
        if (Array.isArray(constructor) && Array.isArray(target)) {
            return target.map(function (target, i) {
                return decode(constructor[i] || constructor[0], target, defers);
            });
        }
        else if (PyjamasDB.contains(constructor)) {
            if (pjs.parent) {
                target = merge(decode(pjs.parent, target, defers), target);
            }
            target = upgrade(pjs, target);
            for (key in pjs.defines) {
                if (pjs.defines.hasOwnProperty(key) && target[key] !== undefined) {
                    instance[key] = decode(pjs.defines[key], target[key], defers);
                }
            }
        }
        return instance;
    }
function decode ( constructor , target , defers ) { var key , instance , pjs ; pjs = PyjamasDB . fetch ( constructor ) || { } ; defers = ( pjs . defers || [ ] ) . concat ( defers || [ ] ) ; instance = construct ( constructor , target , defers ) ; if ( Array . isArray ( constructor ) && Array . isArray ( target ) ) { return target . map ( function ( target , i ) { return decode ( constructor [ i ] || constructor [ 0 ] , target , defers ) ; } ) ; } else if ( PyjamasDB . contains ( constructor ) ) { if ( pjs . parent ) { target = merge ( decode ( pjs . parent , target , defers ) , target ) ; } target = upgrade ( pjs , target ) ; for ( key in pjs . defines ) { if ( pjs . defines . hasOwnProperty ( key ) && target [ key ] !== undefined ) { instance [ key ] = decode ( pjs . defines [ key ] , target [ key ] , defers ) ; } } } return instance ; }
Decodes an object to become an instance of the given constructor
 @param constructor   {function}  Object constructor
 @param target        {object}    Raw object that populates a new instance
 @param [defers]      {Array}     Constructors to defer execution
Decodes an object to become an instance of the given constructor @param constructor { function } Object constructor @param target { object } Raw object that populates a new instance @param [ defers ] { Array } Constructors to defer execution
// If the constructor is an array then it contains the type of the array // so map the target to the correct types // If the constructor is in the Pyjamas database then we need to fetch the Pyjamas // configuration so that we can apply the correct properties to the new instance. // If we have a Pyjamas instance then we need to ensure // that we decode any parent properties before decoding this // object // Before we decode the constructor we need to apply // any defined upgrade functions to the raw object // For each defined value we need to decode it // and recursively apply  the corresponding constructor