Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript: How to pass object by value?

Tags:

javascript

  • 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?
like image 283
vol7ron Avatar asked Sep 27 '11 18:09

vol7ron


People also ask

Can you pass objects by value?

An immutable object's value cannot be changed, even if it is passed a new value. “Passing by value” refers to passing a copy of the value. “Passing by reference” refers to passing the real reference of the variable in memory.

Are objects passed by value in JavaScript?

Javascript always uses the pass by value concept. That means that changing the value of a variable never changes the underlying primitive. The confusing part is when the variables hold an object, a function or an array.

Does JS pass-by-reference or value?

JavaScript is always pass-by-value. This means everything in JavaScript is a value type and function arguments are always passed by value. That being said, object types are a bit more confusing. The confusion lies in the fact that object types are reference types which are passed by value.

How are objects passed in JavaScript?

In JavaScript, object references are values. Because of this, objects will behave like they are passed by reference: If a function changes an object property, it changes the original value. Changes to object properties are visible (reflected) outside the function.


1 Answers

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 
like image 145
user113716 Avatar answered Nov 15 '22 12:11

user113716