今天晚些时候,我正在浏览ejhon.com幻灯片,我发现了以下内容:
提供此代码
function katana () {
this.myvar = true;
}
katana ();
console.info (myvar);
在我编译代码的那一刻,我认为myvar附加到katana函数。实际上,它会附加到窗口对象上,这会污染全局命名空间。
我回到了我的项目,这些项目都采用了相同的方法......有点不同
function katana () {
this.myvar = true;
}
var xyz = new katana();
console.info (myvar);
我有一个函数对象,而不是执行该函数,我只是创建一个新的实例(我实际上并不确定发生了什么)。然后我使用xyz来存储值,并通过原型方法使用这些值来完成一些工作。
让我感到惊讶的是,当我使用FireBug进行一些调试时,xyz不存在。窗口对象没有附加变量。为什么呢?
我做了一些调试,xyz对象附加到窗口>对象,但在DOM中它不明显,没有痕迹。调试窗口中还有一些新东西,一个名为'scopechain'的节点,带有一个调用,并且具有xyz对象的值。
好的,下面发生了什么?这是一个我应该坚持的好方法还是我应该寻找替代方案? 我看了一些问题和答案,我主要是在寻找这种方法在后台做的事情。
答案 0 :(得分: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
。