JavaScript 中的“多态可调用对象”

7
我看到了关于多态可调用对象的文章,并试图让它工作起来,但似乎它们并不真正具有多态性,或者至少它们不尊重原型链。
这段代码输出undefined,而不是"hello there"
这种方法是否不能与原型一起使用,还是我做错了什么?
var callableType = function (constructor) {
  return function () {
    var callableInstance = function () {
      return callableInstance.callOverload.apply(callableInstance, arguments);
    };
    constructor.apply(callableInstance, arguments);
    return callableInstance;
  };
};

var X = callableType(function() {
    this.callOverload = function(){console.log('called!')};
});

X.prototype.hello = "hello there";

var x_i = new X();
console.log(x_i.hello);

1
我刚刚被你的头像和名字所吸引。我猜他的名字是周树人。 - xis
1个回答

6

您需要更改这个:

var X = callableType(function() {
    this.callOverload = function(){console.log('called!')};
});

转换为:

var X = new (callableType(function() {
    this.callOverload = function(){console.log('called!')};
}));

注意在callableType调用周围的new和括号。
括号允许调用callableType并返回函数,该函数用作new的构造函数。
var X = callableType(function() {
    this.callOverload = function() {
        console.log('called!')
    };
});

var someType = X();      // the returned constructor is referenced
var anotherType = X();   // the returned constructor is referenced

someType.prototype.hello = "hello there";  // modify the prototype of
anotherType.prototype.hello = "howdy";     //    both constructors

var some_i = new someType();           // create a new "someType" object
console.log(some_i.hello, some_i);

var another_i = new anotherType();     // create a new "anotherType" object
console.log(another_i.hello, another_i);

someType();      // or just invoke the callOverload
anotherType();

我真的不知道在什么情况下/为什么会使用这个模式,但我想肯定有一些好的理由。


也许我做错了什么,但这似乎破坏了调用实例的能力 - 调用 x_i() 会抛出类似于“对象不是函数”的异常。 - Aaron Yodaiken
@luxun:通过像这样内联使用 new,您立即调用了从 callableType 返回的函数作为构造函数。我认为您错过了的是,您的代码正在向 X 的原型添加,而不是向从 X 返回的构造函数添加。按照我的方式,X 本身成为构造函数,但您可以在另一个变量中引用它。我会添加更新。 - user113716
好的,我明白了。我实际上认为这会使实例可调用,但我看到这不是这种情况。 - Aaron Yodaiken

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接