vol7ron vol7ron - 3 months ago 33
Javascript Question

JavaScript: How to pass object by value?


  • When passing objects as parameters, JavaScript passes them by reference and makes it hard to create local copies of the objects.

    var o = {};
    (function(x){
    var obj = x;
    obj.foo = 'foo';
    obj.bar = 'bar';
    })(o)


    o
    will have
    .foo
    and
    .bar
    .

  • It's possible to get around this by cloning; simple example:

    var o = {};

    function Clone(x) {
    for(p in x)
    this[p] = (typeof(x[p]) == 'object')? new Clone(x[p]) : x[p];
    }

    (function(x){
    var obj = new Clone(x);
    obj.foo = 'foo';
    obj.bar = 'bar';
    })(o)


    o
    will not have
    .foo
    or
    .bar
    .






Question




  1. Is there a better way to pass objects by value, other than creating a local copy/clone?


Answer

Not really.

Depending on what you actually need, one possibility may be to set o as the prototype of a new object.

var o = {};
(function(x){
    var obj = Object.create( x );
    obj.foo = 'foo';
    obj.bar = 'bar';
})(o);

alert( o.foo ); // undefined

So any properties you add to obj will be not be added to o. Any properties added to obj with the same property name as a property in o will shadow the o property.

Of course, any properties added to o will be available from obj if they're not shadowed, and all objects that have o in the prototype chain will see the same updates to o.

Also, if obj has a property that references another object, like an Array, you'll need to be sure to shadow that object before adding members to the object, otherwise, those members will be added to obj, and will be shared among all objects that have obj in the prototype chain.

var o = {
    baz: []
};
(function(x){
    var obj = Object.create( x );

    obj.baz.push( 'new value' );

})(o);

alert( o.baz[0] );  // 'new_value'

Here you can see that because you didn't shadow the Array at baz on o with a baz property on obj, the o.baz Array gets modified.

So instead, you'd need to shadow it first:

var o = {
    baz: []
};
(function(x){
    var obj = Object.create( x );

    obj.baz = [];
    obj.baz.push( 'new value' );

})(o);

alert( o.baz[0] );  // undefined