总是把这两个库中的extend搞混了所以写下来。
backbone中的extend实现了继承:

1 // Helper function to correctly set up the prototype chain for subclasses. 2 // Similar to `goog.inherits`, but uses a hash of prototype properties and 3 // class properties to be extended. 4 var extend = function(protoProps, staticProps) { 5 var parent = this; 6 var child; 7 8 // The constructor function for the new subclass is either defined by you 9 // (the "constructor" property in your `extend` definition), or defaulted 10 // by us to simply call the parent constructor. 11 if (protoProps && _.has(protoProps, 'constructor')) { 12 child = protoProps.constructor; 13 } else { 14 child = function(){ return parent.apply(this, arguments); }; 15 } 16 17 // Add static properties to the constructor function, if supplied. 18 _.extend(child, parent, staticProps); 19 20 // Set the prototype chain to inherit from `parent`, without calling 21 // `parent`'s constructor function and add the prototype properties. 22 child.prototype = _.create(parent.prototype, protoProps); 23 child.prototype.constructor = child; 24 25 // Set a convenience property in case the parent's prototype is needed 26 // later. 27 child.__super__ = parent.prototype; 28 29 return child; 30 }; 31 32 // Set up inheritance for the model, collection, router, view and history. 33 Model.extend = Collection.extend = Router.extend = View.extend = History.extend = extend;
underscore中的extend实现了属性的复制,这是浅复制:

1 _.extend = createAssigner(_.allKeys); 2 3 var createAssigner = function(keysFunc, undefinedOnly) { 4 return function(obj) { 5 var length = arguments.length; 6 if (length < 2 || obj == null) return obj; 7 for (var index = 1; index < length; index++) { 8 var source = arguments[index], 9 keys = keysFunc(source), 10 l = keys.length; 11 for (var i = 0; i < l; i++) { 12 var key = keys[i]; 13 if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key]; 14 } 15 } 16 return obj; 17 }; 18 };
仔细阅读后,backbone中的extend分为4个步骤完成继承:
(1)定义一个子类(返回的对象)
(2)给子类赋值一个function,方法题中调用call方法
(3)将父类的静态属性扩展后(扩展的属性就是函数参数)赋值给子类
(4)将父类的原型扩展(扩展的属性就是该函数的参数)后赋值给子类的原型
这种写法有一点不好,就是完全没有私有变量和私有方法,只能依靠人为的约束