Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript by reference vs. by value [duplicate]

I'm looking for some good comprehensive reading material on when JavaScript passes something by value and when by reference and when modifying a passed item affects the value outside a function and when not. I'm also interested in when assigning to another variable is by reference vs. by value and whether that follows any different rules than passing as a function parameter.

I've done a lot of searching and find lots of specific examples (many of them here on SO) from which I can start to piece together pieces of the real rules, but I haven't yet found a single, well written document that describes it all.

Also, are there ways in the language to control whether something is passed by reference or by value?

Here are some of the types of questions I want to understand. These are just examples - I'm actually looking to understand the rules the language goes by, not just the answers to specific examples. But, here are some examples:

function f(a,b,c) {    a = 3;    b.push("foo");    c.first = false; }  var x = 4; var y = ["eeny", "miny", "mo"]; var z = {first: true}; f(x,y,z); 

When are the contents of x, y and z changed outside the scope of f for all the different types?

function f() {     var a = ["1", "2", "3"];     var b = a[1];     a[1] = "4";     // what is the value of b now for all possible data types that the array in "a" might hold? }  function f() {     var a = [{yellow: "blue"}, {red: "cyan"}, {green: "magenta"}];     var b = a[1];     a[1].red = "tan";     // what is the value of b now and why?     b.red = "black";     // did the value of a[1].red change when I assigned to b.red? } 

If I want to make a fully independent copy of an object (no references whatsoever), what's the best practice way to do that?

like image 281
jfriend00 Avatar asked Jul 07 '11 03:07

jfriend00


People also ask

Is JavaScript copy by reference or value?

When you copy an object b = a both variables will point to the same address. This behavior is called copy by reference value. Strictly speaking in Ruby and JavaScript everything is copied by value. When it comes to objects though, the values happen to be the memory addresses of those objects.

Is JavaScript call by reference?

In JavaScript, that's not possible, so it's not pass-by-reference.

What is the difference between passing by value and passing by reference?

Passing by reference means the called functions' parameter will be the same as the callers' passed argument (not the value, but the identity - the variable itself). Pass by value means the called functions' parameter will be a copy of the callers' passed argument.


2 Answers

My understanding is that this is actually very simple:

  • Javascript is always pass by value, but when a variable refers to an object (including arrays), the "value" is a reference to the object.
  • Changing the value of a variable never changes the underlying primitive or object, it just points the variable to a new primitive or object.
  • However, changing a property of an object referenced by a variable does change the underlying object.

So, to work through some of your examples:

function f(a,b,c) {     // Argument a is re-assigned to a new value.     // The object or primitive referenced by the original a is unchanged.     a = 3;     // Calling b.push changes its properties - it adds     // a new property b[b.length] with the value "foo".     // So the object referenced by b has been changed.     b.push("foo");     // The "first" property of argument c has been changed.     // So the object referenced by c has been changed (unless c is a primitive)     c.first = false; }  var x = 4; var y = ["eeny", "miny", "mo"]; var z = {first: true}; f(x,y,z); console.log(x, y, z.first); // 4, ["eeny", "miny", "mo", "foo"], false 

Example 2:

var a = ["1", "2", {foo:"bar"}]; var b = a[1]; // b is now "2"; var c = a[2]; // c now references {foo:"bar"} a[1] = "4";   // a is now ["1", "4", {foo:"bar"}]; b still has the value               // it had at the time of assignment a[2] = "5";   // a is now ["1", "4", "5"]; c still has the value               // it had at the time of assignment, i.e. a reference to               // the object {foo:"bar"} console.log(b, c.foo); // "2" "bar" 
like image 175
nrabinowitz Avatar answered Oct 27 '22 00:10

nrabinowitz


Javascript always passes by value. However, if you pass an object to a function, the "value" is really a reference to that object, so the function can modify that object's properties but not cause the variable outside the function to point to some other object.

An example:

function changeParam(x, y, z) {   x = 3;   y = "new string";   z["key2"] = "new";   z["key3"] = "newer";    z = {"new" : "object"}; }  var a = 1,     b = "something",     c = {"key1" : "whatever", "key2" : "original value"};  changeParam(a, b, c);  // at this point a is still 1 // b is still "something" // c still points to the same object but its properties have been updated // so it is now {"key1" : "whatever", "key2" : "new", "key3" : "newer"} // c definitely doesn't point to the new object created as the last line // of the function with z = ... 
like image 32
nnnnnn Avatar answered Oct 27 '22 00:10

nnnnnn