当我在全局命名空间下定义局部变量时,它会被同名的实例变量覆盖。
var outerVar;
outerVar = 'outerVar';
this.outerVar = 'thisOuterVar';
console.log(outerVar); // thisOuterVar
然而,在函数内部不会发生同样的情况。
var fun;
fun = function() {
var innerVar;
innerVar = 'innerVar';
this.innerVar = 'thisInnerVar';
return console.log(innerVar); // innerVar
};
fun();
此代码在Firebug中运行。
this.constructor // Window { }
如果我在节点下运行相同的代码,其中this.constructor
为[Function: Object]
,则返回'outerVar'而不是'thisOuterVar',这是有意义的。
为什么它在Window下的行为方式不同?
答案 0 :(得分:1)
如果您在全局空间中在浏览器中运行代码,就像第一个样本一样:
var outerVar;
outerVar = 'outerVar';
this.outerVar = 'thisOuterVar';
console.log(outerVar);
然后一切都在基本的全局空间下运行:window
- 这基本上是浏览器js中所有环境的基本范围。
因此,当您定义var outerVar
之类的值时,它基本上类似于window.outerVar
或this.outerVar
或window['outerVar']
。
但是如果你在匿名函数/对象函数下运行你的代码,如:
fun = function() {
var innerVar;
innerVar = 'innerVar';
this.innerVar = 'thisInnerVar';
return console.log(innerVar); // innerVar
};
this
引用函数(object),var innerVar
引用函数的范围(如基本oop类中的private var)
你可以看一下this.somevar
是公开而var othervar
是私有 - 这些完全不同。
这也是回答你的节点问题,因为在节点一切都在“幕后”的匿名函数下运行 - 这是 commonjs 方式 - 所以在节点中,它与你的匿名函数样本基本相同。
修改强>
正如@bfavaretto正确评论我一样 - this.innerVar
是根据你如何使用它来定义的 - 这意味着如果你将它作为常规函数使用,this
将成为窗口 - 因此是全局的 - 如果你做了一个它的对象(就像我想的那样 - 它将被定义为实例并且是“ public ”):
function func(){
alert(this);
}
func(); //alerts 'window'
var f = new func(); //alerts 'object'
答案 1 :(得分:0)
在全局命名空间中,'a = 5;'在语义上等同于'window.a = 5;'或'this.a = 5;'
答案 2 :(得分:0)
你说,“当我在全局命名空间下定义一个局部变量时......”。这是一个矛盾的术语。当你在全球范围内时,没有“局部变量”这样的东西。至于你的函数内部发生了什么,当你声明var innerVar;
时,你正在创建一个仅存在于该函数范围内的变量。然后,当您在函数内修改this.innerVar
时,您正在修改(或声明)变量innerVar
,而this
恰好是window
当时正好是{{1}} 1}}或者,基本上是全球范围。