0 Replies - 1629 Views - Last Post: 24 March 2014 - 04:46 PM

#1 Dormilich  Icon User is offline

  • 痛覚残留
  • member icon

Reputation: 4138
  • View blog
  • Posts: 13,074
  • Joined: 08-June 10

Extend ES5-style objects

Posted 24 March 2014 - 04:46 PM

This snippet makes use of the object property descriptors defined in ECMAScript 5. this allows to copy non-enumerable properties that would not be caught in a for…in loop.
function mixin(target, source) {
    // exit if nothing is passed
    if (arguments.length === 0) {
        throw new Error("There is no object to extend.");
    }
    // extend an empty object if only one argument is given
    if (arguments.length === 1) {
        source = target;
        target = {};
    }
    // test if target/source are objects
    // otherwise the Object.*Property* methods will throw an error
    if (target === null || typeof target !== "object") {
        throw new Error("Target is not an object.");
    }
    if (source === null || typeof source !== "object") {
        throw new Error("Source is not an object.");
    }
    // use the new ES5 property methods to get *all* properties
    // not only the enumerable ones and retain the property settings
    Object
        .getOwnPropertyNames(source)
        .forEach(function(key) {
            if (!target.hasOwnProperty(key)) {
                Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
            }
        });
    // re-call if more sources are available
    if (arguments.length > 2) {
        // remove primary source
        [].splice.call(arguments, 1, 1); 
        return mixin.apply(this, arguments);
    }
    return target;
}



Usage:
// extending an object
mixin(obj, defaults);

// cloning an object
var clone = mixin(obj);



Test:
var o1 = {
    firstName: "Bertold",
    lastName:  "von Dormilich"
};
var o2 = {
    firstName: "John",
    lastName:  "Doe",
    city:      "Utopia"
};
var o3 = {};
Object.defineProperty(o3, "secret", {
    value:      "My sweet little valentine",
    enumerable: false
});

var obj = mixin(o1, o2, o3);

console.log(o1);
/*
  Object { firstName="Bertold", lastName="von Dormilich", city="Utopia"}
*/

for (var key in obj) {
    console.log("%s: %s ", key, obj[key]);
}
/*
  firstName: Bertold
  lastName: von Dormilich
  city: Utopia 
*/

console.log(obj.secret);
/*
  My sweet little valentine
*/


This post has been edited by Dormilich: 24 March 2014 - 04:47 PM


Is This A Good Question/Topic? 0
  • +

Page 1 of 1