2

I just noticed something weird with cloning and pushing items. Here's example:

let a = { foo: [1,2] };
let b = Object.assign({}, a) // cloning object and getting new reference
a === b // gives false which is what I want

now I do push on object a:

a.foo.push(3)

now a.foo is [1,2,3] but b.foo is also [1,2,3]

but if I do

a.foo = a.foo.concat(4)

a.foo is [1,2,3,4] and b.foo is [1,2,3]

Question is: Why is that?

1
  • the reason a.foo is [1,2,3,4] and b.foo is [1,2,3] is that concat() returns a whole new array which will replace a.foo Commented Jun 20, 2017 at 8:06

5 Answers 5

3

a.foo and b.foo are pointing to the same reference,but .concat() returns a new array so they now are pointing 2 different array reference

Sign up to request clarification or add additional context in comments.

Comments

2

Object.assign does something that is called shallow cloning or shallow copying. If the source value is a reference to an Object, it only copies that reference value.

Check the docs here and read Warning for Deep Clone.

That is also why a push affects both Objects a and b, because it is in fact the same array on which the operation takes place.

The Array.prototype.concat method returns a new Array Object, which you assign to a.foo (a.foo = a.foo.concat(4)), so both foo references will now point to 2 different array objects.

The concat() method is used to merge two or more arrays. This method does not change the existing arrays, but instead returns a new array.

                               Object references

Comments

1

Why is that?

Object.assign({}, a) does shallow copy of your object a

const foo = {bar: []}

const baz = Object.assign({}, foo)

console.log(foo.bar === baz.bar)

But Array.prototype.concat creates new array

const foo = []
const bar = foo.concat()

console.log(foo === bar)

4 Comments

why are you doing foo.bar === baz.bar, explain why foo === baz is false if it is a shalow copy
@AurA Why would it be true?
that would be false because it is an object and object structure gets copied in shallow copy but variables point to the same, that is the reason it is returning false here... It is an empty object but still structure gets copied...
@AurA Doesn't it obvious? Well, atlaest for OP who used this method to do "cloning object and getting new reference". Copy is still a copy though it is shallow.
1

Because in your case a.foo and b.foo reference the same array. so a change in one side will affect the other one, and Array.prototype.concat returns a new array and doesn't alter the first array that's why you got differents results in the second call, as opposed to array.prototype.push which will alter the initial array.

Array.prototype.concat:

The concat() method is used to merge two or more arrays. This method does not change the existing arrays, but instead returns a new array.

array.prototype.push:

The push() method adds one or more elements to the end of an array and returns the new length of the array.

You may also need to read What is the most efficient way to deep clone an object in JavaScript?, because Object.assign() will just copy the reference to the exisiting objects.

Comments

0

read here

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

assign dont do a deep copy, so a.foo and b.foo point to same array so when you push it gets added to same array

but when you do concat it actually returns new array and now both arrays are different

2 Comments

then why a === b gives false ?
assume it like so a = {x : y} now b = {} then b.x = a.x you should see that a is clearly different but key have same values ..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.