javascript - Extending an object by reference -
i have extend method extends objects expect in javascript:
var obja = {a: true}; var objb = extend({b:false}, obja); console.log(objb); // {a: true, b: false} however, extend source's (obja) properties onto target (objb) object reference changes made source reflected in target after fact, so:
var obja = {a: true}; var objb = extend({b: false}, obja); console.log(objb); // {a: true, b:false} obja.a = false; console.log(objb); // {a: false, b:false} for instance, when modify object (which assigned reference) things working way them to:
var obja = {a:{a: true}}; var objb = _.extend({b: false}, obja); console.log(objb) // {a:{a:true}, b:false}; obja.a.a = false; console.log(objb); // {a:{a:false}, b:false}; so in other words, when changes made obja's non-object literal properties (or value isn't assigned reference) changes reflected in objb.
i'm sure isn't possible without additional helper method depend on sort of object watch method triggered whenever object changes.
thoughts?
code extend method:
(l).extend = (l).merge = function () { var args = (l).fn.__args(arguments, [{ deep: 'bool' }, { '*': 'obj:object' } ]), target = (l)._object || args.obj, keys = [], obj, objs, copy, key, i, o; // collect potential objects merge objs = (l).filter(args, function (value, index) { if (index !== "obj" && (l).isplainobject(value) && !((l).isequal(target, value))) { return value; } }); // when target object not selected globally if (!args.obj) { target = objs.shift(); } // when target object not selected globally , single object // passed extend library if (!(l)._global && !objs.length) { target = this; objs[0] = args.obj; } // when boolean passed go deep if (args.deep) { // build property reference used prevent never ending loops (l).each(objs, function (index, value) { keys.push((l).keys(value)); keys = (l).flatten(keys); }); // add properties nested objects (l).deep(target, function (depth, index, obj, ref) { if ((l).indexof(keys, index) === -1) { (i = 0; < objs.length; i++) { (key in objs[i]) { if ((l).isplainobject(obj)) { copy = objs[i][key]; obj[key] = copy; } } } } }, "*"); } // merge first level properties after going deep (i = 0; < objs.length; i++) { if ((obj = objs[i]) !== null) { (key in obj) { copy = obj[key]; if (target === copy) { continue; } target[key] = copy; } } } return (l).fn.__chain(target); };
what mentioned here prototypal inheritance of javascript:
var obja = {a: false}; var objb = object.create(obja); objb.b = false; console.log(objb.a, objb.b); // true, obja.a = false; console.log(objb.a, objb.b); // false, false of course if objb overrides a property, lose link, because javascript found property a in object objb, therefore won't in prototype's chain.
using ecmascript 5 methods, have extend function that:
function extend(properties, proto) { var object = object.create(proto); var descriptor = {}; object.getownpropertynames(properties).foreach(function(name) { descriptor[name] = object.getownpropertydescriptor(properties, name); }); return object.defineproperties(object, descriptor); } var obja = {a: true}; var objb = extend({b: false}, obja); console.log(objb.a, objb.b); // true, false obja.a = false; console.log(objb.a, objb.b); // false, false
Comments
Post a Comment