考虑以下代码:
function klass( z ) {
this.a = z;
return this;
}
var b = klass( 5 );
var c = new klass( 9 );
当我在Chrome中运行并检入控制台时,b
的格式为DOMWindow
,而c
的格式为klass
。
虽然两者都具有属性a,但实际上它们都是 klass 的实例。
答案 0 :(得分:6)
当像这样调用一个函数时
klass(6); //called function invocation
this
将设置为全局对象,或者,如果您处于严格模式,undefined
因此,第一个示例(没有new
)将返回附加了新a
属性的全局对象。在严格模式下,它会抛出错误,因为this
将设置为undefined
,并且您无法将a
属性添加到undefined
。
使用new
new klass( 9 ); //called constructor invocation
this
值设置为新对象,并且从函数中隐式返回 - 无需说return this
为了完整性,当您在对象上调用函数作为方法时:
foo.method(); //called method invocation
在这种情况下, this
将设置为对象 - foo
。
当您使用apply(或call)
调用函数时method.apply(foo) //called apply invocation
this
设置为您指定的任何内容 - foo
再次
修改强>
我在回答中提到strict mode
。页面使用严格模式(如果有)
"use strict"
在它的最顶端。
答案 1 :(得分:6)
如果没有new
,你的函数只会在绑定的this
上运行,在你的情况下是DOMWindow。没有创建新实例,在窗口对象上设置了a
属性。调用该方法两次破坏了之前的结果。
试试这个:
var b = klass(5)
log.info(b.a)
log.info(b == window) // b is actually the window object
log.info(window.a) // also 5
var c = klass(6)
log.info(b.a) // now set to 6
log.info(c == b) // c and b are the same
答案 2 :(得分:3)
绝对不一样:
var a = klass(42);
console.log(a.a); // 42
var b = klass(69);
console.log(b.a); // 69
console.log(a.a); // 69
如果你不打电话给new
,你就不会得到任何新的东西。