9

我在使用 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。当尝试通过 new 创建该类的实例时az.classes['test](),它可以正常工作并a.hello()执行。但是当我调用该方法时az.getClass('test'),该方法又返回相同的构造函数,但是当我var b=new az.getClass('test');在这里说它b时它失败了undefined!失败了b.hello()!!我不明白这种行为!az.classes['test']()new和 new有什么区别az.getClass('test')。他们不是一回事吗??

4

4 回答 4

5

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

所以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')();执行az.getClass返回类 getter 函数的表达式,并尝试将其用作构造函数。然后您的实例尝试使用().

或重构,它这样做:

// 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!
于 2013-04-24T05:40:25.580 回答
3

JavaScript 中的构造函数可以返回一个值,该值替换通常由“new”表达式返回的值。

所以new az.getClass("test")()将首先评估az.getClass("test")哪个将返回一个函数。然后,您使用 () 调用该函数,该函数将返回 undefined,因为它没有返回值。

于 2013-04-24T05:37:44.470 回答
1

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

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

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

于 2013-04-24T05:35:36.447 回答
0

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

相当于先获取类:

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

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

进而:

b = b();

使用全局对象调用类构造函数 this

于 2013-04-24T05:36:47.397 回答