Beginners question about Vars

Thanks in advance to anyone who can give me the answer to the following test case I have done during the course.

var a=[7,8,10];
var b=a;
b[0]+=5;
console.log(a,b);

The result for a and b is the same

[12, 8, 10],[12, 8, 10] 

I was expecting to get

[7, 8, 10],[12, 8, 10] 

What am I not getting correct?

1 Like

You are not creating a copy of the array doing this, just changing the variable with which you reference it

Do it with this tool and you will see a visual representation

http://pythontutor.com/javascript.html

To copy an array you need to use things like spread operator, slice() or concat()

3 Likes

ieahleen is absolutely correct :+1:

In JavaScript primitive variables (e.g. 'number’s & 'string’s) are copied and evaluated when assigned, so:

let numA = 42;
let numB = numA;
numB = numB * 100;
console.log(numA); // 42
console.log(numB); // 4200
console.log(numA === numB); // false
console.log(numA === 42); // true

While aggregated variables (e.g. 'object’s and 'array’s) are copied and evaluated “by reference”. (Think of it like the object or array variable is just an address. When you tell an architect that you want a house built exactly like that house, the same blueprint is used, but each house has it’s own address.) So:

let arrA = [0, 42, 100];
let arrB = arrA; // like a child giving the same address as their parent
let arrC = [42, 42, 42]; // but this is a brand new address
arrB = [42, 42, 42];
console.log(arrA); // [42, 42, 42]
console.log(arrA === arrB); // true
console.log(arrB === arrC); // false

One way you can compare complex variables is by stringifying them, like:

let nestedArrayA = [0, [1, [2], 3], 4]
let nestedArrayB = [0, [1, [2], 3], 4]
console.log(nestedArrayA === nestedArrayB) // false
console.log(JSON.stringify(nestedArrayA) === JSON.stringify(nestedArrayB)) // true

One last caveat, because aggregated objects are handled by reference, when you learn about const, you need to know that the object/array reference is constant, but you can change (or mutate) the contents of a const object/array, just like you can rearrange furniture in your house or apartment without moving to a new address. So:

const houseA = ['kitchen', 'bathroom', 'bedroom']
houseA.push('garage') // mutating the existing address works
houseA = ['kitchen', 'bathroom', 'bedroom', 'garage'] // building a new house at the same address does NOT work
2 Likes
var a=[7,8,10];
var b=[...a];
b[0]+=5;
console.log(a,b);

From ES6 you can use the spread syntax for clone an array, if not as ieahleen said you could just be creating a new variable referencing the same place in memory where your current array is already created.

1 Like

I’m a huge fan of the spread operator, but it is important to mention that it can only be used safely on shallow arrays and objects, or else you end up with an inconsistent mashup of values and references, e.g.

let a=[1, 2, { nested: [3, 4]}];
let b=[...a];
b[0] = null;
b[2].nested[0] = 99
// shallow level was a copy
console.log('a[0]:', a[0]); // 1
console.log('b[0]:', b[0]); // null
// deeper level was a reference
console.log('a[2].nested[0]:', a[2].nested[0]); // 99
console.log('b[2].nested[0]:', b[2].nested[0]); // 99
1 Like

Well, also slice() and concat() can be used safely only with monodimensional arrays - it’s just how arrays are

Visual representation:

2 Likes

Thanks to all for the replies.
I can continue with my training.

1 Like