令人费解的Javascript构造函数问题

问题描述:

一个非常令人困惑的问题,我正在使用JavaScript。看一下下面的代码..令人费解的Javascript构造函数问题

az={ 
    classes:{ 
     test:function(){ 
     this.hello=function(name){ 
      alert('hello '+name); 
     } 
     } 
    }, 
    getClass:function(name){ 
    return az.classes[name]; 
    } 
}; 
var a=new az.classes['test'](); 
a.hello('foo'); 
var b= new az.getClass('test')(); 
b.hello();// fails !!! 

中的代码,如果你注意到我们有一个对象az.classes内定义的类。当试图通过新的az.classes['test]()创建该类的实例时,它可以正常工作,并且a.hello()可以正常执行。但当我打电话的方法az.getClass('test'),而这反过来返回相同的构造函数,但它失败时,我说var b=new az.getClass('test');在这里它的说bundefined!和b.hello()失败!我不明白这种行为!新的az.classes['test']()和新的az.getClass('test')有什么区别。他们不是一回事吗?

+1

尝试'var b = new(az.getClass('test'))();'改为。那么b就会像 – user2264587 2013-04-24 05:34:56

+0

@ gurvinder372你必须对我读一个不同的问题。我看到'getClass:function(name)' – Phil 2013-04-24 05:35:05

当实例化构造函数时,第一个parens指示在构造函数中使用什么。

因此new az.classes['test']();将执行表达式az.classes['test']并使用结果函数作为构造函数。

或者重构,它这样做:

// new az.classes['test']() 
//      ^expression left of here used as constructor! 
var MyConstructor = az.classes['test']; 
new MyConstructor(); 

然而,new az.getClass('test')();执行它返回类的getter函数的表达式az.getClass,并尝试使用它作为构造函数。然后你的实例试图用()执行。

或者重构,它这样做:

// new az.getClass('test')(); 
//    ^expression left of here used as constructor! 
var MyConstructor = az.getClass; 
var instance = new MyConstructor('test'); 
instance(); // obviously not gonna work. 

看到区别?

您可以通过各地应该返回构造函数的表达式包装更小括号解决这个问题:

new (az.getClass('test'))(); 
//      ^expression left of here used as constructor! 

或者通过保存构造函数引用一个局部变量,然后用它的下一行。这可能更加理智和可读:

var MyConstructor = az.getClass('test'); 
new MyConstructor(); 
//    ^expression left of here used as constructor! 
+0

酷!这表明它!! ..感谢密尔 – user1179563 2013-04-24 06:24:40

这是括号(运算符优先级)的问题。这应该工作:

var b = new (az.getClass('test'))(); 

http://jsbin.com/odajet/1/edit

var b = new az.getClass('test')();

相当于第一获取类:

var b = new az.classes.getClass('test'); 

b为现在的az.test,而不是它的一个实例。

然后:

b = b(); 

调用类的构造函数与全局对象,因为这

在JavaScript中构造函数可以返回一个值,它取代了通常会被返回的值“新“表达。

所以new az.getClass("test")()将首先评估az.getClass("test")这将返回一个函数。然后用()调用该函数,由于它没有返回值,它将返回未定义的函数。

+0

+1对于实际回答 – Phil 2013-04-24 05:40:29

+0

+1的问题,另一个答案实际上有点不对 - 操作符优先级决定在'()'之后调用'new'。 – 2013-04-24 06:31:05