1

I am getting back to JS after a very long break and as I was going over "Jump Start JavaScript" book. In part of it says:

if your array contains an array as one of its items, it will be copied by reference. In other words, if the original array changes, so will the copy.

So I tried to do in code but JS doesn't work! (correct me if I'm wrong)

Then in SOF I saw this thread:

Reference to slice of an array

Should I consider this as mistake/error in the book?!

Thanks, AK

Community
  • 1
  • 1
amit kohan
  • 1,612
  • 2
  • 25
  • 47

3 Answers3

2

It's unfortunate that the phrase by reference gets thrown around like it does, because it has a perfectly clear meaning that is completely different from one the being (mis-) used here. All values in JavaScript are copied/passed by value. When dealing with objects, that value is a reference to the object. But it's still a value that is copied.

When you make a shallow copy of an array using slice, the elements that are references to objects have those same references copied to the new array. That is, the same position in both arrays will refer to the same object. So, yes, changing one changes the other because there is no other; they are the same object.

Proof:

var arr = [[7, 6, 5], 4, 5];
var copy = arr.slice();

arr[0][0] = 88;
console.log(copy[0][0]); // 88

Tangent on pass-by-reference

If you can't write a function like this:

function swap(arg1, arg2) {
    var temp = arg1;
    arg1 = arg2;
    arg2 = temp;
}

...that actually swaps the values of two variables:

var one = [1, 2, 3];
var two = ["a", "b", "c"];

swap(one, two);
console.log(one) // same as before

...then your language does not support pass by reference.

More pass-by-value

Wait, doesn't the following demonstrate that JavaScript must be pass-by-reference:

function Test(arg1) {
    this.arg = arg1;
}

var one = [1, 2, 3];    
var x = new Test(one);
x.arg[0] = 5;

console.log(one); // it's been updated!

No! If you think this then you still haven't understood what pass by reference actually is. Yes, a reference to the original array was passed to Test, but it was passed by value. In other words, x.arg refers to the same object in memory as one but it is not an alias for one. To prove this, you simply need to assign something new to x.arg:

x.arg = ["new array"];

This does not affect one. These two variables are independent. JavaScript is strictly pass-by-value. There are no exceptions.

Wayne
  • 59,728
  • 15
  • 131
  • 126
  • No, you are being mislead by the word reference. "Pass by reference" has a meaning *much older* than the JavaScript language. And JavaScript is *not* pass by reference. – Wayne Jan 18 '14 at 01:37
  • The *value* passed in the case of objects is the reference. It doesn't sound like you understood the point of my last example. – Wayne Jan 18 '14 at 01:37
  • Read this. It's about Java, not JavaScript, but the same logic applies. http://javadude.com/articles/passbyvalue.htm – Wayne Jan 18 '14 at 01:39
  • No, I'm not. http://stackoverflow.com/questions/13104494/does-javascript-pass-by-reference – Wayne Jan 18 '14 at 01:42
  • There are languages in which the `swap` above would modify the global versions of the variables. That's what pass-by-reference is. JavaScript does not pass by reference. It passes a reference by value. – Wayne Jan 18 '14 at 01:43
  • That link does not demonstrate pass by reference. It demonstrates that a reference to the same object was passed by value into a function and then that same object was updated. I never said otherwise. There are *no exceptions* to pass by value. Your link demonstrates pass by value. – Wayne Jan 18 '14 at 01:46
0
var subarray = [1, 2, 3];
var main_array = ['a', subarray, 'b'];

var slice = main_array.slice(0, 2);
console.log(slice); => ['a', [1, 2, 3]]

subarray[0] = 10;
console.log(slice); => ['a', [10, 2, 3]]
megawac
  • 10,953
  • 5
  • 40
  • 61
Barmar
  • 741,623
  • 53
  • 500
  • 612
0

In JavaScript it´s also correct to initialize an Array with the "new" keyword:

var arr = new Array();
arr.push("0. Index");
arr.push("1. Index");
document.body.appendChild(document.createTextNode(JSON.stringify(arr)));

In every programming language I know, the new keyword stands for creating an object. And also in every programming language I know, an object is Call-By-Reference and not Call-By-Value. So the book tells you the truth. That´s a JavaScript special: Because PHP arrays are always Copy-By-Value, if you do not use explicit the & for making it to a reference.

To clear this this disussion finally, execute this code below in you browser and compare the used memory size. A 2nd reference to an already existing object should cause lower memory usage than 2 seperated arrays:

First this one:

var arr1 = new Array();
for (var i = 0; i < 11; i++)
{
arr1.push(i);
}
var arr2 = arr2;

Second this one:

var arr1 = new Array();
var arr2 = new Array();
for (var i = 0; i < 11; i++)
{
arr1.push(i);
arr2.push(i);
}

Or simply try this one and see the results:

var arr1 = new Array();

for (var i = 0; i < 11; i++)
{
arr1.push(i);
}
var arr2 = arr1;
arr2[5] = "test";
document.body.appendChild(document.createTextNode("arr2 => " + JSON.stringify(arr2)));
document.body.appendChild(document.createTextNode("arr1 => " + JSON.stringify(arr1)));

If the output prints on the 5th index for both arrays "test" instead of 5, it´s for sure Call-By-Reference, as your book said. If not, it´s Copy-By-Value.

alpham8
  • 1,314
  • 2
  • 14
  • 32