1

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

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 { }

如果我在 node, where this.constructoris下运行相同的代码[Function: Object],它会返回 'outerVar' 而不是 'thisOuterVar' 这很有意义。

为什么它在 Window 下的行为不同?

4

3 回答 3

1

如果您像第一个示例一样从全局空间在浏览器中运行代码:

var outerVar;

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

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

所以当你定义价值时,var outerVar它基本上就像window.outerVaror this.outerVaror window['outerVar']

但是,如果您在匿名函数/对象函数下运行代码,例如:

fun = function() {
  var innerVar;
  innerVar = 'innerVar';
  this.innerVar = 'thisInnerVar';
  return console.log(innerVar);      // innerVar
};

this引用函数(对象)和引用函数的var innerVar范围(如基本 oop 类中的私有 var) 您可以将其视为this.somevar公共私有-var othervar它们完全是不同的东西。

这也回答了您的节点问题,因为在节点中,一切都在“幕后”匿名函数下运行 - 这是commonjs方式 - 所以在节点中它与您的匿名函数示例基本相同。

编辑: 正如@bfavaretto 正确评论我的那样——它this.innerVar是根据你使用它的方式定义的——这意味着如果你将它用作常规功能当然this将是窗口——因此是全局的——如果你把它作为一个对象(就像我想的那样——它将被定义到实例并且是“公共的”):

function func(){
   alert(this);
}

func(); //alerts 'window'

var f = new func(); //alerts 'object'
于 2013-04-24T19:11:49.027 回答
0

在全局命名空间中,'a = 5;' 在语义上等同于 'window.a = 5;' 或 'this.a = 5;'

于 2013-04-24T19:08:34.320 回答
0

你说,“当我在全局命名空间下定义一个局部变量时......”。这在术语上是矛盾的。当您在全局范围内时,没有“局部变量”之类的东西。至于函数内部发生的事情,当您声明时,var innerVar;您正在创建一个仅存在于该函数范围内的变量。然后,当您在函数内部进行修改时,您正在修改(或声明)当时发生的任何情况this.innerVar的变量,在这种情况下,它是或基本上是全局范围。innerVarthiswindow

于 2013-04-24T19:12:40.210 回答