当我覆盖 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.Model
this
来自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