我使用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');
时它失败了b
是undefined
!!而b.hello()
失败了!!我不明白这种行为!新az.classes['test']()
和新az.getClass('test')
之间有什么区别。他们不是一回事吗?
答案 0 :(得分:5)
在实例化构造函数时,第一个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.
看到区别?
你可以通过在应该返回构造函数的表达式周围包含更多的parens来解决这个问题:
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!
答案 1 :(得分:3)
JavaScript中的构造函数可以返回一个值,该值将替换“new”表达式通常返回的值。
因此new az.getClass("test")()
将首先评估将返回函数的az.getClass("test")
。然后,您将使用()返回该函数,该函数将返回undefined,因为它没有返回值。
答案 2 :(得分:1)
答案 3 :(得分:0)
var b = new az.getClass('test')();
相当于第一次上课:
var b = new az.classes.getClass('test');
b现在是类 az.test
,而不是它的实例。
然后:
b = b();
使用全局对象调用类构造函数作为此