JavaScript中的new关键字和对象作用域

3
今天稍晚些时候,我正在浏览ejhon.com的幻灯片,发现了以下内容:
将此代码给出
function katana () {
this.myvar = true;
}
katana ();
console.info (myvar);

在我编译代码后的那一刻,我认为myvar被附加到katana函数上了。实际上它会被附加到window对象上,这会污染全局命名空间。

我回到我的项目中,它们都使用相同的方法...只是略微有所不同。

function katana () {
this.myvar = true;
}
var xyz = new katana();
console.info (myvar);

我有一个函数对象,但我没有执行该函数,而是创建了一个新实例(我并不确定发生了什么)。然后我使用xyz存储值,并通过原型方法使用这些值来完成一些工作。
令我惊讶的是,在使用FireBug进行调试时,xyz不存在。没有变量附加到窗口对象上。为什么?
我进行了更多的调试,发现xyz对象附加到window > object上,但在DOM中它不明显且没有痕迹。调试窗口中还出现了一个新节点,称为“scopechain”,其中包含一个调用和xyz对象的值。
好的,底层发生了什么?这是我应该坚持使用的好方法还是应该寻找替代方案? 我已经查看了一些问题和答案,主要是想知道这种方法在后台做了什么。

阅读此链接:http://ejohn.org/apps/learn/ - andres descalzo
其实我刚才只是在浏览这个。我只是想要一个更深入的解释,因为那些幻灯片只展示了结果。 - Omar Abid
1个回答

3
当你使用new katana()时,Javascript调用katana函数,并将一个新的空对象作为this。一旦它返回,假设已经初始化完成,那么新对象(或者katana返回的任何对象,只要是对象)就被设置为其“原型”(它将继承字段等内容的对象)与katana函数的原型相同。
第一次阅读时,这句话可能并不太容易理解。简化版本是,当你使用new katana()时,Javascript会创建一个将成为katana实例的对象,并让katana函数对其进行初始化。当你使用katana()时,this基本上是在实例方法调用中调用堆栈中使用过的最后一个对象。(如果你的调用者是x.foo,那么this == x)。如果没有这样的对象,那么this就是window
至于为什么xyz没有显示出来,这是因为你使用了var来声明变量。这改变了作用域。如果你去掉它,你就会看到一个window.xyz

好的回答。我主要想知道地下正在发生什么。FireBug中的新“scopechain”节点怎么样?此外,xyz似乎附加到窗口对象上,但在DOM中不存在。 - Omar Abid
我不使用FireBug(或者说火狐浏览器)。'scopechain'的东西可能是Firefox跟踪作用域的方式。但在Chrome中似乎不存在,至少我不认为它是Javascript/ECMAScript的标准功能。 - cHao

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接