如何覆盖主干中的extend方法

How does one override the extend method in backbone

本文关键字:extend 方法 何覆盖 覆盖      更新时间:2023-09-26

在我的主干应用程序中,我想要一个特定类A的所有子类(从中扩展的子类)的列表。为了实现这一点,我想覆盖默认的extend方法,但是我的(也许是天真的)方法不起作用:

var A = Backbone.Model.extend({
  /* ... */
}, {
  __children: [],
  extend: function () {
    var Klass = this;
    result = Klass.__super__.extend.apply(Klass, arguments);
    Klass.__children.push(result);
    return result;
  }
});
B = A.extend({}, {className: "B"});
A.__children // === []

为什么这不起作用,在重写extend方法时是否有一些魔力?

原来extend方法是特殊的。正如你从中看到的那样

> Backbone.Model.extend
function (protoProps, classProps) {
    var child = inherits(this, protoProps, classProps);
    child.extend = this.extend;
    return child;
  }

extend方法会被父类中的一个覆盖,无论你试图如何处理它。因此,解决这个问题的方法是在之后"修复"扩展方法:

var enableChildTracking = function (Klass) {
    var old_extend = Klass.extend;
    Klass.__children = [];
    Klass.extend = function () {
        var That = this;
        var result = old_extend.apply(That, arguments);
        That.__children.push(result);
        result.__children = [];
        return result;
    };
};
var A = Backbone.Model.extend({});
enableChildTracking(A);
B = A.extend({}, {className: "B"});
C = A.extend({}, {className: "C"});
A.__children.map(function (child) {return child.className}); /* == ["B", "C"] */

当然,这种方式也可以直接覆盖Backbone.Model中的扩展,或者在进行扩展时发送事件或调用回调(la ruby)。