Why does reference = null not affect the reference

2019-07-07 07:37发布

问题:

I know this works, but I don't know why or the reasoning behind why it was made to work this way:

var foo = [5, 10];
var bar = foo;
console.log(foo); //[5, 10]
console.log(bar); //[5, 10]
bar[0] = 1; 
console.log(foo); //[1, 10]
bar = null;
console.log(foo); //[1, 10]

I would have expected not just bar to become null, but foo as well. I'd love some help understanding this.

回答1:

The difference is between rebinding and mutating operations.

bar[0] = 1

is mutating; it affects the object that bar points to.

bar = null

is rebinding; it just affects what the identifier bar means.



回答2:

When you do bar = null; that just assigns something to the value of the bar variable. It does not affect what used to be assigned to bar. That object continues to live on and if there are other references to it, it stays alive with its value untouched.

When you do this:

var foo = [5, 10];
var bar = foo;

You have three entities. You have an array [5,10] and two variables each with a reference to that array. If you change the array, then since both variables point to the same array, you will see that change no matter which variable you reference the array through.

But, if you set bar = null, that just affects the bar variable which then no longer has a reference to the array. It doesn't affect the array at all which is still pointed to by foo.

In fact, if you did this:

var foo = [5, 10];
var bar = foo;
bar = [20,30];

You'd have the same sort of result. After the second line of code both bar and foo pointed to the same array, but after the third line, bar now points to a new array and only foo points to the original array. The key is realizing that there's a difference between using bar to modify the object it points to as in bar[0] = 1 versus reassigning the whole value of bar as in bar = [20,30]. In the first case, the underlying object that both foo and bar point to is changed. In the second case, the underlying object that bar originally pointed to is not touched. Instead, bar is changed to point a new object and the prior object is not touched.



回答3:

You have two pointers to the array. Bar = foo copies the original pointer. Dereferencing bar does not dereference foo.

Read more @ http://snook.ca/archives/javascript/javascript_pass



回答4:

Reference, but it's definition is just a pointer to some object. When you assign null to bar, you simply delete this "pointer" that was stored in bar, making it no longer point to object.

Imagine this as an address, written on sheets of paper. If sheet foo and bar have same address on it and you issue a command: go to address written on sheet foo and put something in house there, after operation is done, naturally, whoever looks at any of those sheets and checks out that address, will find those changes. Now your assignment of null is just same as wiping this address from sheet with eraser. It doesn't touch neither any other sheets, nor house in any way.



回答5:

I like to think of variables as labels. Makes explaining them easier.

//Create an array containing 5 and 10, and put the label "foo" on it
var foo = [5, 10];
//Put the label "bar" on the thing with the label "foo"
var bar = foo;      
console.log(foo); //[5, 10]
console.log(bar); //[5, 10]
//Take the thing labeled "bar" (which also has the label "foo") and change the first element to 1
bar[0] = 1;         
console.log(foo); //[1, 10]
//Take the label "bar" and attach it to nothing
bar = null;
console.log(foo); //[1, 10]

var foo = [5, 10]; var bar = foo; console.log(foo); //[5, 10] console.log(bar); //[5, 10] bar[0] = 1; console.log(foo); //[1, 10] bar = null; console.log(foo); //[1, 10]



回答6:

When you do

var foo = [5, 10];

It creates a reference to an array, like this

foo --->  [5, 10]

When you assign bar to foo, you now have

foo --->  [5, 10]

bar ------^

When you call

bar[0] = 1;

you get

foo --->  [1, 10]

bar ------^

where foo and bar point to the same object.

When you call

bar = null;

you now have

foo --->  [1, 10]