我们知道,父类中的属性有this、static和prototype三种。我们常用的继承方式有两种:
将这两种方式综合使用,并在此基础上,使用delete删除不需要的属性,以及通过重写方法来覆盖父属性,以达到完美继承的效果。
/** * Filename: PrefectExtend.js * Description: 该程序将通过原型继承、对象冒充和覆盖三套机制,来完美实现 * Js的继承。 * Date: 2012/3/7 */ /** * 父类Animal,及其this、静态、prototype属性的构造。 */ Animal = function(tail) { this.tail = tail || "动物的尾巴"; // 父类的this属性 this.kinds = "动物"; Animal.instanceCounter ++; // 父类的静态属性 } Animal.instanceCounter = 0; Animal.prototype = { // 父类的prototype属性 happy: function() { console.log("摇动>" + this.tail); }, eat: function() { console.log("动物吃生的"); }, run: function() { console.log("动物四条腿跑"); }, fight: function() { console.log("动物往死里打"); } } // 这里如果不这样做,那么Animal.prototype.constructor == Object,详见参考资料[2] Animal.prototype.constructor = Animal; /** * 1. 对象冒充: 继承this及static属性 */ // 子类Person Person = function(name) { Person.superclass.call(this); // this属性继承 delete this.tail; // 删除不需要的this属性 this.name = name || "猎空de代码"; for(var p in Animal) { // static属性继承 Person[p] = Animal[p]; } } Person.superclass = Animal; /** * 2. 原型继承 */ F = function() {} // 空壳函数,用于清除Animal的构造属性(this和静态) F.prototype = Animal.prototype; Person.prototype = new F(); delete Person.prototype.fight; //删除不需要的prototype属性 Person.prototype.constructor = Person; /** * 3. prototype方法覆盖 */ Person.prototype.eat = function() { console.log(this.name + "吃熟的"); } // 创建实例 var person = new Person(); console.log("姓名: " + person.name); console.log(person.kinds); console.log("实例数目" + Person.instanceCounter); person.happy(); person.eat(); person.run();
程序运行结果:
参考资料:
[1] Ext 江湖,大漠穷秋,北京:电子工业出版社,2012.1 (这段程序,基本是模仿该书写的)
[2] JavaScript类和继承:constructor属性