Backbone源码学习之extend
extend函数在backbone大概就20来行代码包括注释,对学习Javascript中“类”的继承很是好的学习资料。
下面先贴出Backbone中的源码,其中涉及到underscore库中几个实用函数_.has();.create();.extend();
// 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 extend = function(protoProps, staticProps) { // 通过js中this定义,this是运行中确定。方便“类”继承。 var parent = this; var child; // The constructor function for the new subclass is either defined by you // (the "constructor" property in your `extend` definition), or defaulted // by us to simply call the parent constructor. // 如果protoProps属性中含有constructor及是一个构造函数,但是这里有不够安全。child即继承这个构造函数。 if (protoProps && _.has(protoProps, 'constructor')) { child = protoProps.constructor; } else { //否则继承this(父类的构造函数) child = function(){ return parent.apply(this, arguments); }; } // Add static properties to the constructor function, if supplied. //给子类增加静态属性(方法) _.extend(child, parent, staticProps); // Set the prototype chain to inherit from `parent`, without calling // `parent`'s constructor function and add the prototype properties. //创造一个空对象获取父类的原型对象和增加原型对象,赋值给子类的原型对象,丰富子类原型对象。 child.prototype = _.create(parent.prototype, protoProps); // 调整子类constructor使其指向正确 child.prototype.constructor = child; // Set a convenience property in case the parent's prototype is needed // later. // 方便子类调用父类原型对象上的方法 child.__super__ = parent.prototype; // 返回子类 return child; };
通看backbone中的extend使用最常Javascript的继承方式,构造函数继承对象的属性,原型对象中继承方法(减少内存)。下面看一个JS中最常见的继承实例。
//创建一个Person“类” var Person = function(name,age,job){ this.name = name; this.age = age; this.job = job; } //Person.prototype原型对象 Person.prototype={ sayName:function(){ alert(this.name); }, constructor:Person //重写constructor确保指向正确 }; //继承 var Man = function(name,age,job,sex){ Person.apply(this,argument);//通过函数apply的方法使this.age,this.name,this.job中的this指向到Man实例化的对象中 this.sex=sex; } //原型对象的继承 //方法一,这种方法重复构造函数一次 Man.prototype = new Person(); //方法二,创建一个空构造函数 var F = function(){}; F.prototype = new Person(); Man.prototype = new F(); Man.prototype.constructor = Man;
当然这种方式肯定没有Backbone中的extend优雅也没有他的健壮!