javascript Window对象没有局部变量吗?

时间:2013-04-24 19:02:56

标签: javascript

当我在全局命名空间下定义局部变量时,它会被同名的实例变量覆盖。

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下的行为方式不同?

3 个答案:

答案 0 :(得分:1)

如果您在全局空间中在浏览器中运行代码,就像第一个样本一样:

var outerVar;

outerVar = 'outerVar';
this.outerVar = 'thisOuterVar';
console.log(outerVar);

然后一切都在基本的全局空间下运行:window - 这基本上是浏览器js中所有环境的基本范围。

因此,当您定义var outerVar之类的值时,它基本上类似于window.outerVarthis.outerVarwindow['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}}或者,基本上是全球范围。