17

This may be an old question but I'm really curious about the nature of copying objects by reference as an assignment in javascript.

Meaning that if

var a = {}; var b = a; a.name = "Renato"; console.log(b); Object {name: "renato"} 

I'm kind of new to javascript and this really caught my attention to have a shallow copy as a default for Object assignment. I searched that in order to create a hard copy, you have to create a mixin. I was wondering why was this chosen as the default since it's transformation seems to be very implicit. Thanks!

2
  • 1
    wondering why was this chosen as the default Because in most cases it would be the best option, .. Javascript is a Garbage Collected environment, one of it's strengths is be able to pass objects about without having to worry about memory leaks. And the other advantage is speed.. Commented Nov 5, 2016 at 1:29
  • In addition, deep copies are more costly. Doing shallow copy by default gives the programmer the freedom to explicitly choose which one they want to perform Commented Nov 5, 2016 at 1:32

1 Answer 1

29

Objects and arrays are treated as references to the same object. If you want to clone the object, there are several ways to do this.

In later browsers, you can do:

var b = Object.assign({}, a); 

If you want to go for a library, lodash provides _.clone (and _.cloneDeep):

var b = _.clone(a); 

If you don't want to do either of those methods, you can just enumerate through each key and value and assign them to a new object.

Oftentimes it's valuable for them to be treated as references when passing through multiple functions, etc. This isn't the case for primitives like numbers and strings, because that would feel pretty counterintuitive in most cases.

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

5 Comments

You could also add the good old JSON.parse/stringify.. var b = JSON.parse(JSON.stringify(a))
@Keith also another idea, but that won't work for objects that have functions as values.
If we have { a: 'b', c: function(){} }, stringifying it will result in "'{'a':'b'}'"
Indeed, I should have mentioned if the data was serializeable.. It was just meant as another option, were if running on older browsers, you could do this without having to say load lodash/underscore etc.
If you're writing in ES6, you can also use the object spread operator: let b = {...a};. Looks like this isn't supported in many browsers (yet), so you should only do this if you are using a transpiler (like babel) and targeting ES5 or earlier.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.