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

时间:2013-04-24 05:28:28

标签: 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')之间有什么区别。他们不是一回事吗?

4 个答案:

答案 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)

括号(运算符优先级)存在问题。这应该有效:

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

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

答案 3 :(得分:0)

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

相当于第一次上课:

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

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

然后:

b = b();

使用全局对象调用类构造函数作为此