2011-12-23 45 views
6

考虑以下代码:在Javascript中使用新功能与不使用它相同吗?

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

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

当我在Chrome上运行它,并在控制台检查,b原来是DOMWindow型的,而cklass型。

尽管两者都具有属性a,实际上两者都是实例klass

  • 正在使用或不使用新的,相同的?
  • 这个例子是一样的,但在其他情况下不同吗?
  • 效率或行为有差异吗?
+0

有趣的问题,我想知道这一点。 – 2011-12-23 02:57:14

+3

从你问题中的信息来看,它们显然不一样,因为结果对象有不同的类型。如果你调查什么_other_属性的第一个具有你会看到其中的差别... – nnnnnn 2011-12-23 03:25:53

回答

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将被设置为object-foo

当你调用一个函数适用(或呼叫)

method.apply(foo) //called apply invocation 

this设置为任何你再次指明foo

编辑

我在答复中提到strict mode 。一个页面使用严格模式,如果它有

"use strict" 

在它的最上面。

+0

如何获得严格的模式? – Thilo 2011-12-23 03:07:17

+1

@Thilo - 见编辑 – 2011-12-23 03:08:17

+0

+1,但在你的第二个对我想你指的是“'this'将设置...” – nnnnnn 2011-12-23 03:26:42

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,你没有得到任何新的东西。

+1

*“如果你不叫新的,你没有得到任何新的东西。” *它的简洁深刻的。 :) – 2011-12-23 03:45:42

+0

但是,当然你可以在JS中不用'new'来创建新的对象。 – Kos 2011-12-23 17:40:30

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 
相关问题