当我覆盖 a 的clone()方法时Backbone.Model,有没有办法从我的植入中调用这个覆盖的方法?像这样的东西:
var MyModel = Backbone.Model.extend({
    clone: function(){
        super.clone();//calling the original clone method
    }
})
当我覆盖 a 的clone()方法时Backbone.Model,有没有办法从我的植入中调用这个覆盖的方法?像这样的东西:
var MyModel = Backbone.Model.extend({
    clone: function(){
        super.clone();//calling the original clone method
    }
})
你会想要使用:
Backbone.Model.prototype.clone.call(this);
这将使用(当前模型)的上下文调用原始clone()方法。Backbone.Modelthis
来自Backbone 文档:
简要介绍 super:JavaScript 没有提供调用 super 的简单方法——定义在原型链更高层的同名函数。如果您覆盖了一个核心函数,如 set 或 save,并且您想调用父对象的实现,则必须显式调用它。
var Note = Backbone.Model.extend({
 set: function(attributes, options) {
 Backbone.Model.prototype.set.apply(this, arguments);
 ...
 }    
});
您还可以使用作为__super__对父类原型的引用的属性:
var MyModel = Backbone.Model.extend({
  clone: function(){
    MyModel.__super__.clone.call(this);
  }
});
Josh Nielsen为此找到了一个优雅的解决方案,它隐藏了很多丑陋之处。
只需将此代码段添加到您的应用程序即可扩展 Backbone 的模型:
Backbone.Model.prototype._super = function(funcName){
    return this.constructor.prototype[funcName].apply(this, _.rest(arguments));
}
然后像这样使用它:
Model = Backbone.model.extend({
    set: function(arg){
        // your code here
        // call the super class function
        this._super('set', arg);
    }
});
根据 geek_dave 和 charlysisto 给出的答案,我编写了此代码以this._super(funcName, ...)在具有多个继承级别的类中添加支持。它在我的代码中运行良好。
Backbone.View.prototype._super = Backbone.Model.prototype._super = function(funcName) {
        // Find the scope of the caller.
        var scope = null;
        var scan = this.__proto__;
        search: while (scope == null && scan != null) {
            var names = Object.getOwnPropertyNames(scan);
            for (var i = 0; i < names.length; i++) {
                if (scan[names[i]] === arguments.callee.caller) {
                    scope = scan;
                    break search;
                }
            }
            scan = scan.constructor.__super__;
        }
        return scan.constructor.__super__[funcName].apply(this, _.rest(arguments));
    };
一年后,我修复了一些错误并使事情变得更快。下面是我现在使用的代码。
var superCache = {};
// Hack "super" functionality into backbone. 
Backbone.View.prototype._superFn = Backbone.Model.prototype._superFn = function(funcName, _caller) {
    var caller = _caller == null ? arguments.callee.caller : _caller;
    // Find the scope of the caller.
    var scope = null;
    var scan = this.__proto__;
    var className = scan.constructor.className;
    if (className != null) {
        var result = superCache[className + ":" + funcName];
        if (result != null) {
            for (var i = 0; i < result.length; i++) {
                if (result[i].caller === caller) {
                    return result[i].fn;
                }
            }
        }
    }
    search: while (scope == null && scan != null) {
        var names = Object.getOwnPropertyNames(scan);
        for (var i = 0; i < names.length; i++) {
            if (scan[names[i]] === caller) {
                scope = scan;
                break search;
            }
        }
        scan = scan.constructor.__super__;
    }
    var result = scan.constructor.__super__[funcName];
    if (className != null) {
        var entry = superCache[className + ":" + funcName];
        if (entry == null) {
            entry = [];
            superCache[className + ":" + funcName] = entry;
        }
        entry.push({
                caller: caller,
                fn: result
            });
    }
    return result;
};
Backbone.View.prototype._super = Backbone.Model.prototype._super = function(funcName) {
        var args = new Array(arguments.length - 1);
        for (var i = 0; i < args.length; i++) {
            args[i] = arguments[i + 1];
        }
        return this._superFn(funcName, arguments.callee.caller).apply(this, args);
    };
然后给出这个代码:
var A = Backbone.Model.extend({ 
 //   className: "A",
    go1: function() { console.log("A1"); },  
    go2: function() { console.log("A2"); },  
    });
var B = A.extend({ 
 //   className: "B",
    go2: function() { this._super("go2"); console.log("B2"); },  
    });
var C = B.extend({ 
 //   className: "C",
    go1: function() { this._super("go1"); console.log("C1"); },
    go2: function() { this._super("go2"); console.log("C2"); }  
    });
var c = new C();
c.go1();
c.go2();
控制台中的输出是这样的:
A1
C1
A2
B2
C2
有趣的是,类 C 调用this._super("go1")扫描类层次结构,直到它在类 A 中被命中。其他解决方案不这样做。
PS 取消注释className类定义的条目以启用_super查找的缓存。(假设这些类名在应用程序中是唯一的。)
如果你只想调用 this._super(); 不将函数名称作为参数传递
Backbone.Controller.prototype._super = function(){
    var fn = Backbone.Controller.prototype._super.caller, funcName;
    $.each(this, function (propName, prop) {
        if (prop == fn) {
            funcName = propName;
        }
    });
    return this.constructor.__super__[funcName].apply(this, _.rest(arguments));
}
最好使用这个插件:https : //github.com/lukasolson/Backbone-Super