使用var that = this
时是复制还是引用。看来this
是一个特殊的对象,因此that
应该是一个引用。这意味着当this
更改时,that
也应该更改吗?显然不是这样,因为that
保持不变。
任何人都可以澄清吗?为什么var that = this
是一种“价值复制”?
答案 0 :(得分:6)
它正在将称为对象引用的值从this
复制到变量that
。并不是说它是一个特殊的对象,而是JavaScript中 all 对象的引用方式(包括数组和函数):变量(参数,属性等)中存储的是引用到内存中其他位置的对象,而不是对象的副本。
说你有这个:
var a = {
answer: 42
};
这将创建一个新对象,并将引用存储在a
中。在内存中,您有类似以下内容:
+−−−−−−−−−−−−+ a:Ref3554−−−−−−>| (object) | +−−−−−−−−−−−−+ | answer: 42 | +−−−−−−−−−−−−+
我已经使用Ref3554表示参考值,但这纯粹是概念性的。您永远不会在代码中看到实际值。
执行此操作时:
var b = a; // Copies the value
它将a
(引用)中的值复制到b
:
a:Ref3554−−−+ | +−−−−−−−−−−−−+ +−−>| (object) | | +−−−−−−−−−−−−+ b:Ref3554−−−+ | answer: 42 | +−−−−−−−−−−−−+
与您的示例相同,只是用this
代替a
,用that
代替b
。
这意味着当
this
更改时,that
也应该更改吗?
this
在范围内不能更改。但是a
可以,所以让我们继续a
。假设我这样做:
a = {
question: "Life, the Universe, and Everything!"
};
我创建了一个新对象并将其分配给a
。 b
会怎样?
什么都没有:
+−−−−−−−−−−−−−−−+ a:Ref4269−−−−−−+| (object) | +−−−−−−−−−−−−−−−+ | question: ... | +−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−+ b:Ref3554−−−−−−>| (object) | +−−−−−−−−−−−−+ | answer: 42 | +−−−−−−−−−−−−+
请注意,a
是如何获得新参考的(Ref4269)。这对b
毫无影响。 a
和b
没有以任何方式链接(您的示例中的this
和that
也没有链接)。它们只是在一段时间内恰好包含相同的值,然后(如上所述)它们不再存在,因为其中一个被更改了。
但是让我们回到他们都指向同一件事的时候:
var a = {
answer: 42
};
var b = a;
a:Ref3554−−−+ | +−−−−−−−−−−−−+ +−−>| (object) | | +−−−−−−−−−−−−+ b:Ref3554−−−+ | answer: 42 | +−−−−−−−−−−−−+
假设我更改了a
和b
都引用的对象的状态?
a.answer = 27;
b
会发生什么?好吧,b
不变,但是它指向的对象与a
指向的对象相同,并且该对象的状态刚刚被更改,因此自然而然地看到了新状态,无论您使用哪个变量获取对对象的访问权限:
a:Ref3554−−−+ | +−−−−−−−−−−−−+ +−−>| (object) | | +−−−−−−−−−−−−+ b:Ref3554−−−+ | answer: 27 | +−−−−−−−−−−−−+
答案 1 :(得分:2)
不是这样。 io.Writer
引用与that
完全相同的对象:
this
如果您想知道new function ( ) {
var that = this;
this.x = 5;
console.log( that );
}
在内部函数中为何可以不同。基本上这只是阴影。 JavaScript中的每个常规函数调用都有其自己的this
,因此无法访问外部范围的任何this
。这个例子:
this
与此类似:
new function ( ) {
var that = this;
console.log( this === that ); // true
new function ( ) {
console.log( this === that ); // false
};
console.log( this === that ); // true
}
但是箭头功能不是这种情况:
var a = { };
var b = a;
console.log( a === b ); // true
(function ( ) {
var a = { };
console.log( a === b ); // false
})();
console.log( a === b ); // true