4

我们使用 John Resig 的 inherit.js。这使我们可以访问方便的_super()函数来调用父函数。太棒了,但是今天我被一个问题难住了,我this._super()无法从内部调用 a setTimeout,即使我绑定了这个:

代码示例

var Person = Class.extend({
  init: function(isDancing){
  this.dancing = isDancing;
},
    dance: function(){
        return this.dancing;
    }
});

var Ninja = Person.extend({
    init: function(){
        this._super( false );
},
dance: function(){
    window.setTimeout(function(){
        // Call the inherited version of dance()
        return this._super();
    }.bind(this),50);
});

this._super()未定义!到底是怎么回事?

4

2 回答 2

5

要完成这项工作,您需要在子类方法中捕获 _super 方法,如下所示:

dance: function(){
    // capture the super method for later usage
    var superMethod = this._super;
    window.setTimeout(function(){
        return superMethod();
    },50);
};

这有效,而您的代码无效的原因是,extend()inherit.js 中的方法在this._super运行覆盖的方法之前捕获了超类的方法。然后它运行您的代码,并在您的代码运行后将 _super 恢复为运行前设置的任何值。该操作发生在 inherit.js 的以下代码中

      var tmp = this._super;

      // Add a new ._super() method that is the same method
      // but on the super-class
      this._super = _super[name];

      // The method only need to be bound temporarily, so we
      // remove it when we're done executing
      var ret = fn.apply(this, arguments);        
      this._super = tmp;

      return ret;

所以更具体一点;当原始代码运行时,用作 setTimeout 参数的函数被绑定到原始对象。它不起作用的原因是,即使this引用了正确的对象,也this._super引用了其他东西,因为this._super在方法运行之前被重置为指向它所指向的任何东西。可能它没有设置,所以 的值this._super很可能只是undefined

于 2013-09-26T12:09:21.790 回答
2

这显示了如何丑陋Class的实现。该_super属性将仅在dance运行期间可用,并在此后被删除(或恢复),因为它需要特定于当前执行的方法。您将需要获取对“当前”_super值的引用,并从超时中调用它。简而言之:

dance: function(){
    // Call the inherited version of dance()
    window.setTimeout( this._super.bind(this), 50);
}
于 2013-09-26T13:04:58.737 回答