Backboneextend
与 Underscore 不同extend
。下划线extend
只不过是一个for
用于(浅)复制对象属性的循环:
_.extend = function(obj) {
each(slice.call(arguments, 1), function(source) {
for (var prop in source) {
obj[prop] = source[prop];
}
});
return obj;
};
Backboneextend
是其内部inherits
功能的包装器:
var extend = function(protoProps, classProps) {
var child = inherits(this, protoProps, classProps);
child.extend = this.extend;
return child;
};
//...
// Helper function to correctly set up the prototype chain, for subclasses.
// Similar to `goog.inherits`, but uses a hash of prototype properties and
// class properties to be extended.
var inherits = function(parent, protoProps, staticProps) {
var child;
// [Bunch of code for properly setting up the prototype chain and elided]...
return child;
};
注意 and 中的调用return child
:它们都创建并返回新的东西,它们不会修改它们的参数。extend
inherits
使用_.extend
将视图“类”混合到现有对象中的问题:
_.extend(App.Views.ListView, Backbone.View.extend({});
是它_.extend
不会对原型做任何事情,_.extend
也不会神奇地将对象转换为函数,所以你不能调用给你new
的东西_.extend
。您可以将属性混合到视图“类”中,但您必须将属性混合到prototype
视图中并将视图分配给其最终目的地,以便您获得以下功能App.Views.V
:
var V = Backbone.View.extend({ ... }); // Create the view.
_.extend(V.prototype, App.Views.V); // Mix App.Views.V into its prototype.
App.Views.V = V; // Replace App.Views.V with our view function.
演示:http: //jsfiddle.net/ambiguous/5KSbw/
所有这些诡计都会使必须扩展和维护此代码的可怜灵魂感到困惑,因此我建议不要这样做。你最好使用一个单独的对象来保存你的默认值:
var DEFAULTS = {
Views: { ... }
};
然后明确引用这些默认值:
App.Views.ListView = Backbone.View.extend({
myVar: DEFAULTS.Views.ListView.myVar,
//...
});
但是,您将遇到问题,如果您只是复制参考DeeperList
,则必须显式复制其内容以避免更改版本:DEFAULTS
App.Views.ListView = Backbone.View.extend({
DeeperList: _.extend({}, DEFAULTS.Views.ListView.myVar),
//...
});
如果DeeperList
包含对象或数组,则需要使用 jQuery 的$.extend
withtrue
作为第一个参数来获取深层副本:
App.Views.ListView = Backbone.View.extend({
DeeperList: $.extend(true, {}, DEFAULTS.Views.ListView.myVar),
//...
});