上QQ阅读APP看书,第一时间看更新
5.2.2 JS.Class
项目地址:http://code.google.com/p/jsclassextend/
从它的设计来看,它是师承Dean Edwards的Base2,相似的类工厂实现还有mootools,第5.2.3小节的 simple-inheritance。它是通过父类构造器的extend方法来产生自己的子类,里面存在一个开关,防止在生成类时无意执行construct方法。
如Base2的base2.__prototyping,mootools的klass.$prototyping。它创建子类时,也不通过中间的函数来断开双方的原型链,而是使用父类的实例来做子类的原型,这点实现得非常精巧。
源码解读如下。
var JS = { VERSION: '2.2.1' }; JS.Class = function(classDefinition) { //返回目标类的真正构造器 function getClassBase() { return function() { //它在里面执行用户传入的构造器construct //preventJSBaseConstructorCall是为了防止在createClassDefinition辅助方法中执行父 //类的construct if (typeof this['construct'] === 'function' && preventJSBaseConstructorCall === false) { this.construct.apply(this, arguments); } }; } //为目标类添加类成员与原型成员 function createClassDefinition(classDefinition) { //此对象用于保存父类的同名方法 var parent = this.prototype["parent"] || (this.prototype["parent"] = {}); for (var prop in classDefinition) { if (prop === 'statics') { for (var sprop in classDefinition.statics) { this[sprop] = classDefinition.statics[sprop]; } } else { //为目标类添加原型成员,如果是函数,那么检测它还没有同名的超类方法,如果有 if (typeof this.prototype[prop] === 'function') { var parentMethod = this.prototype[prop]; parent[prop] = parentMethod; } this.prototype[prop] = classDefinition[prop]; } } } var preventJSBaseConstructorCall = true; var Base = getClassBase(); preventJSBaseConstructorCall = false; createClassDefinition.call(Base, classDefinition); //用于创建当前类的子类 Base.extend = function(classDefinition) { preventJSBaseConstructorCall = true; var SonClass = getClassBase(); SonClass.prototype = new this();//将一个父类的实例当作子类的原型 preventJSBaseConstructorCall = false; createClassDefinition.call(SonClass, classDefinition); SonClass.extend = this.extend; return SonClass; }; return Base; };
创建一个Animal类与一个Dog子类。
var Animal = JS.Class({ construct: function(name) { this.name = name; }, shout: function(s) { console.log(s); } }); var animal = new Animal(); animal.shout('animal'); // animal var Dog = Animal.extend({ construct: function(name, age) { //调用父类构造器 this.parent.construct.apply(this, arguments); this.age = age; }, run: function(s) { console.log(s); } }); var dog = new Dog("dog", 4); console.log(dog.name); dog.shout("dog"); // dog dog.run("run"); // run
演示静态成员的实现如下。
var Shepherd = Dog.extend({ statics: { //静态成员 TYPE: "Shepherd" }, run: function() { //方法链,调用超类同名方法 this.parent.run.call(this, "fast"); } }); console.log(Shepherd.TYPE); //Shepherd var shepherd = new Shepherd("shepherd", 5); shepherd.run(); //fast
JS.Class虽然功能稍微薄弱些,但简洁得惊人。我们可以在它的基础上学习 Base2,mootools的实现。