Why is this object not passed by reference when assigning it something else?

I know that in JS objects are passed by reference, for example:

function test(obj) { obj.name = 'new name'; } var my_obj = { name: 'foo' }; test(my_obj); alert(my_obj.name); // new name 

But why doesn’t work below:

 function test(obj) { obj = {}; } var my_obj = { name: 'foo' }; test(my_obj); alert(my_obj.name); // foo 

I set the object to {} (empty), but it still says foo .

Can anyone explain the logic behind this?

+50
javascript pass-by-reference
Feb 24 2018-12-12T00:
source share
4 answers

If you are familiar with pointers, then you can take an analogy. You are actually passing a pointer, so obj.someProperty will dereference this property and actually override it, while simply overriding obj destroy the pointer and not overwrite the object.

+66
Feb 24 2018-12-12T00:
source share

Because JavaScript actually passes objects by pass copy- reference.

When you pass my_obj to your test function, a copy of the link to this object is passed. As a result, when re-assigning an object to test , you really only redirect a copy of the link to the original object; your original my_obj remains unchanged.

+29
Feb 24 2018-12-12T00:
source share

Because you are rewriting a link, not an object.

 // Create a new object and assign a reference to it // to the variable my_obj var my_obj = { name: 'foo' }; // Pass the reference to the test function test(my_obj); // Assign the reference to a variable called obj // (since that is the first argument) function test(obj) { // Create a new (empty) object and assign a reference to it to obj // This replaces the existing REFERENCE obj = {}; } // my_obj still has a reference to the original object, // because my_obj wasn't overwritten alert(my_obj.name); // foo 
+26
Feb 24 2018-12-12T00:
source share

Javascript does not have support for passing by reference (although objects are passed by reference and this link is maintained until it is overwritten by the assignment, for example, using = ), but you can simulate the ref C # keyword using the following method:

 function test(obj) { obj.Value = {}; //obj.Value = {name:"changed"}; } var my_obj = { name: 'foo' }; (function () { my_obj = {Value: my_obj}; var $return = test(my_obj); my_obj = my_obj.Value; return $return; }).call(this); alert(my_obj.name); // undefined, as expected // In the question this returns "foo" because // assignment causes dereference 

Of course, you can use global functions and the call function without arguments, in which case the links are not skipped as follows:

 var obj = { name: 'foo' }; function test() { obj = {}; } test(); alert(obj.name); // undefined 

If you have all the code in closure, then everything is simpler and higher, as global global namespaces do not pollute:

 (function(){ var obj = { name: 'foo' }; function test() { obj = {}; } test(); alert(obj.name); // undefined }).call(this); 

The aforementioned “globals inside closure” technique is good if you need to port some C # code with ref arguments to Javascript. For example. The following C # code:

 void MainLoop() { // ... MyStruct pt1 = CreateMyStruct(1); MyStruct pt2 = CreateMyStruct(2); SwapPoints(ref pt1, ref pt2); // ... } void SwapPoints(ref MyStruct pt1, ref MyStruct pt2) { MyStruct tmp = pt1; pt1 = pt2; pt2 = tmp; } 

can be ported to javascript using something like:

 (function(){ var pt1, pt2; function CreateMyStruct(myvar) { return {"myvar":myvar} } function MainLoop() { // ... pt1 = CreateMyStruct(1); pt2 = CreateMyStruct(2); console.log("ORIG:",pt1,pt2); SwapPoints(); console.log("SWAPPED:",pt1,pt2); // ... } function SwapPoints() { var tmp = pt1; pt1 = pt2; pt2 = tmp; } MainLoop(); }).call(this); 

or if you need to use local variables and function arguments, then the solution can be based on the first example of my answer as follows:

 (function(){ function CreateMyStruct(myvar) { return {"myvar":myvar} } function MainLoop() { // ... var pt1 = CreateMyStruct(1); var pt2 = CreateMyStruct(2); console.log("ORIG:",pt1,pt2); (function () { pt1 = {Value: pt1}; pt2 = {Value: pt2}; var $return = SwapPoints(pt1, pt2); pt1 = pt1.Value; pt2 = pt2.Value; return $return; }).call(this); console.log("SWAPPED:",pt1,pt2); // ... } function SwapPoints(pt1, pt2) { var tmp = pt1.Value; pt1.Value = pt2.Value; pt2.Value = tmp; } MainLoop(); }).call(this); 

Indeed, I must say that Javascript is not enough when it does not have a native ref ! The code will be much simpler.

+5
Nov 19 '12 at 10:34
source share



All Articles