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

Puzzling Javascript constructor issue

本文关键字:问题 构造函数 Javascript 令人费解      更新时间:2023-09-26

一个非常令人费解的问题,我有与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')的区别是什么?它们不是一回事吗?

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

因此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!

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

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

这是括号(操作符优先级)的问题。这应该可以工作:

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();

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