【发布时间】:2014-01-08 07:17:15
【问题描述】:
我知道调用没有“new”关键字的函数会将其所有属性吐出到全局上下文中。但是我看到了一些奇怪的行为,这段 Javascript 代码:
function Test3() {
var a=0;
this.inc = function() {
return ++a;
};
this.noInc = function() {
return a;
};
this.testRef = function() {
return this;
};
return {
inc: inc,
testRef: testRef,
noInc: noInc
};
}
var o = Test3(); // Put func properties on global context
var o2 = Test3(); // Put func properties on global context (replacing properties above??)
// Both "o" and "o2" maintain their own copy of "a" (closure)
alert("o: " + o.inc());
alert("o: " + o.inc());
alert("o: " + o.inc()); // Will output 3 (as expected)
alert(noInc()); // Output: 1 (This seems to not be affected by o.inc() calls - expected)
// However...
alert("o2: " + o2.inc());
alert("o2: " + o2.inc());
alert("o2: " + o2.inc());
alert("o2: " + o2.inc()); // Will output 4 (as expected)
alert(noInc()); // Will output 4 (seems to share with o2), but why?
alert(o === window); // false
alert(o.testRef() === o); // true (I thought testRef() would be on global context?)
alert(o.testRef() === window); // false (^^)
alert(o2 === window); // false
alert(o2.testRef() === o2); // true (I thought testRef() would be on global context?)
alert(o2.testRef() === window); // false (^^)
alert(testRef() === window); // true (How come this is here? Look at comments above)
当我们调用
var o = Test()时,这里到底发生了什么?Test()在什么上下文中执行。由于缺少new关键字,我相信Test3()中的this会引用窗口? “o”指的是什么?它只是在全局上下文中声明的变量吗?如果以上为真,那么 o 和 o2 如何能够维护 Test3 的局部变量“a”的单独副本。我知道我们在这里有闭包,但是为什么“o2”和“window”共享变量“a”的相同副本,而不是“o”
-
当我执行 var o = Test3() 然后执行 alert(o.testRef() === window) 时,它显示为 false。所以执行后:
var o = Test3(); var o2 = Test3();
Test3() 的属性似乎有 3 个副本。一个在“o”上,另一个在“o2”上,一个在全局上下文上。
但是“o”和“o2”上怎么会有任何 - 我没有用“new”关键字调用Test3(),所以这应该只指全局上下文?
【问题讨论】:
-
帮自己一个忙,将
"use strict";这一行添加到脚本的顶部。 -
在 JSBin 中工作。我认为它默认启用了“严格”。尝试严格使用;但 JSBin 抱怨那条线。 “严格”会做什么?
-
@TahaAhmad 你放的是
"use strict";还是use strict;?您应该使用带引号的那个... -
在“严格”模式下,在没有上下文的情况下调用的函数中
this的值是undefined而不是window,所以这些分配都会失败。 -
我明白了......但是,在这种情况下,我想了解这里发生了什么,其中“this”隐式默认为全局上下文。
标签: javascript scope closures