1

Say I make an object, copy it (by reference) then nullify it:

let obj = {
  prop: 'one'
}

let otherObj = obj

console.log(otherObj === obj); //true

console.log(obj.prop); //one

obj = null;

console.log(otherObj.prop); //shouldn't this be Uncaught TypeError: Cannot read property 'prop' of null"?

Shouldn't otherObj also be null since they are the same object?

Andrew Li
  • 55,805
  • 14
  • 125
  • 143
skube
  • 5,867
  • 9
  • 53
  • 77
  • 1
    no, you're just changing what the var points to, not the target itself. if you modified the object, both vars would reflect that. think of the 2nd var as an alias; you remove the nickname, not the person. – dandavis Mar 25 '17 at 23:43

5 Answers5

3

You have to differentiate between the object and the reference to that object. Variables obj and otherObj just hold a reference to the object, a pointer pointing to it in memory. They are not copies of the object, and they are not the same object. They point to the same object.

To illustrate this more clearly, I'll explain this line-by-line. When you do:

let obj = {
    prop: 'one'
}

You're creating a new reference, like this:

enter image description here

obj just points to a spot in memory where the object resides, called a reference. Next, you do:

let otherObj = obj

Which is equivalent to this:

enter image description here

Here, you assign the reference of obj to otherObj. They now both refer to the same object in memory, though they are completely independent of each other. otherObj is a shallow copy of obj's reference, so they both refer to the same object but are separate. Per the link:

In that case a new object B is created, and the fields values of A are copied over to B.

[...]

If the field value is a reference to an object (e.g., a memory address) it copies the reference, hence referring to the same object as A does

Finally you do this:

obj = null

Which is like this:

enter image description here

The reference from obj to the object in memory is essentially severed and obj now points to null, or nothing. Since obj and otherObj were independent of each other, nothing happens to otherObj and it still points to the object in memory. obj and otherObj are separate references themselves, but refer to the same object. When you modify the object in memory, it's reflected on both references, but when you modify a reference by breaking the reference to the memory location, nothing happens to the other.

Community
  • 1
  • 1
Andrew Li
  • 55,805
  • 14
  • 125
  • 143
0

No, because the reference is lost in the exact moment that you make the new assignment obj = null , otherObj will still contain the old reference.

in other words, since you modify the object (eg. changing some of its fields), both otherObj and obj will see the updates, but when you re-assign one of them you break the bond and each one will refer to a different location in memory.

Karim
  • 8,454
  • 3
  • 25
  • 33
0

No, to understand why you need to understand the concept of "references".

In your example this bit of code "creates" your object:

let obj = {
    prop: 'one'
}

And in this case, "obj" is NOT the object itself (like memory location), but is an object "reference" - basically it is a pointer to a pointer.

Before you set "obj" to null, you also assigned "otherObj" as a reference to the SAME object. You had 2 references at this point.

When you set "obj" to null, the object still existed and was still referenced by "otherObj". It will be kept in memory, at least until it is no longer reference by "otherObj" either. If you set both references to null, then you would not longer be able to access the object itself and would likely make it available to be freed by the Javscript engine.

This is a very important concept - if you pass a variable into a function, that argument is a "reference" to the object (except for things like strings and numbers, which are essentially immutable). You can reassign the variable outside the function and the argument will remain intact.

Also, on the flipside - while both references point to the same object changes to the members are reflected by both references. If you want two different copies, you have to do things like "cloning" an object - not merely referencing it.

Understanding references is critical to managing closures in Javascript.

Steve Harris
  • 344
  • 1
  • 6
0

You should distinguish between a deep copy and a shallow copy. What you're doing is called shallow copy. Here is the visualization:

Shallow copy

enter image description here enter image description here enter image description here

Deep copy

enter image description here enter image description here enter image description here

For a shallow copy, both of your objects (obj and otherObj) refer to the same memory location. That's why when you change the value of one object, the other will be updated as well.

Meanwhile, with a deep copy, each object has its own memory location. When you change one object's value, it does not affect the other.

You can read more from this post.

Community
  • 1
  • 1
Triet Doan
  • 11,455
  • 8
  • 36
  • 69
-1

No, because variables are untyped in JavaScript. This means that the JavaScript engine can determine the type of a variable from the information it contains. In Visual Basic, a very similar kind of variable is called a "variant".

So if you say

let otherObj = obj;

where obj is an object value, you now have two variables which know they are objects and have the same object value (without going into how objects are implemented as references).

So if you now execute

obj = null;

the value of obj is over-written with the value null (which incidentally has a data type "null", which only supports one value: null).

Obviously assigning a new value to one variable isn't supposed to change the value held in another variable. Programming languages depend on this.

So after the value of obj had been updated, otherObj contains the same object value it did before: an object with property "prop" with value "one".

traktor
  • 17,588
  • 4
  • 32
  • 53