在Javascript中使用new是否与不使用它相同?

时间:2011-12-23 02:55:27

标签: javascript class object new-operator

考虑以下代码:

function klass( z ) {
    this.a = z;
    return this;
}

var b = klass( 5 );
var c = new klass( 9 );

当我在Chrome中运行并检入控制台时,b的格式为DOMWindow,而c的格式为klass

虽然两者都具有属性a,但实际上它们都是 klass 实例

  • 使用或不使用新的,相同的?
  • 这个例子是否相同但在其他情况下有所不同?
  • 效率或行为是否存在差异?

3 个答案:

答案 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,你就不会得到任何新的东西。