【发布时间】:2012-01-09 05:47:09
【问题描述】:
Javascript 通过引用传递对象。这很有意义。但是一旦你开始操纵这些对象,一切都会以一种看起来不直观的方式运行。我举个例子:
var a, b;
a = {}
b = a;
a['one'] = {};
console.log( JSON.stringify(a) );
// outputs: {"one":{}}
console.log( JSON.stringify(b) );
// outputs: {"one":{}}
这一切都很好,因为现在b 有一个指向a 的指针,因此预计将内容分配给a 也会影响b。
但是如果我这样做:
a = a['one'];
console.log( JSON.stringify(a) );
// outputs: {}
console.log( JSON.stringify(b) );
// outputs: {"one":{}}
这让我很惊讶。我希望a 和b 仍然是相同的(并且是{},因为a['one'] 之前设置为{} 和a 设置为a['one'])。
但事实并非如此。似乎a 在分配给新事物时失去了对b 的引用,但b 保持a 在a 失去对b 的引用之前设置的值。
但是如果我这样做:
a['two'] = 2;
console.log( JSON.stringify(a) );
// outputs: {"two":2}
console.log( JSON.stringify(b) );
// outputs: {"one":{"two":2}}
什么? a 显然失去了对b 的引用,但b 似乎仍然对a 有一些引用。
空对象{} 是否指向内存中的某个位置,所以引用它的每个变量现在都指向同一个位置?
对此有深入了解的人可以给我解释一下吗?
【问题讨论】:
-
“现在
b有一个指向a的指针”是谎言开始的地方。 “现在b指向与a相同的位置”是解决方法。 -
"Javascript 通过引用传递对象" - 不,它没有。它按值传递,但在对象的情况下,传递的值是对对象的引用,而不是对象本身的副本。这是一个重要的区别。如果您不是在谈论函数参数,那么谈论“传递”值或引用是没有意义的,但无论如何:如果它通过引用传递,那么您可以更改原始变量
a指向的对象更改第二个变量b指向的内容 - 你绝对不能这样做(无论是否在函数中)。 -
@nnnnnn 我现在很困惑。如果您假设 Javascript 通过引用完成所有操作,那么这如何导致能够通过更改
b来更改a指向的对象?似乎a和b是相互独立的引用,就像指针一样,而且似乎Javascript 仅通过引用传递,它只是不传递对变量的引用,它传递对变量所引用的引用。 -
@Seth Carnegie:"Pass by reference" 是一个标准的非语言特定的编程术语,许多语言都支持它而不向程序员公开指针,但 JavaScript 不这样做。您所说的是正确的:“按值传递引用”是 JavaScript 对象所发生的事情。我很抱歉我之前没能这么说。我想我们一直在绕圈子,因为术语,抱歉。
标签: javascript pointers reference