所谓的“多亲继承”,同样是借用面向对象语言的说法。
以前看过一些文章,介绍如何让js拥有面向对象语言的“继承”特性。
但在实际项目中,很少使用这些晦涩的方法来模拟“继承”的实现。
既然js提倡的是函数式编程,那就让我们忘掉“继承”,“接口”这些OO特性,
体验函数式编程的代码重构方法,达到“提取共性,封装变化”的目的。
//借用策略模式的思路,创建功能类Printable,所有继承它的子类都将具有print的功能 var Printable = function(){}; Printable.prototype = { print: function(){ console.log('The instance of '+this.name+' is printable!'); }, toString: function(){ return 'Printable'; } }; //创建功能类Clonable,所有继承它的子类都将具有clone的功能 var Clonable = function(){}; Clonable.prototype = { clone: function(){ console.log('The instance of '+this.name+' is clonable!'); }, toString: function(){ return 'Clonable'; } }; // 为顶层对象Object添加extend方法,所有对象都能直接调用到这个方法。 Object.prototype.extend = function(parentClass){ var parentClassName = parentClass.prototype.toString(); // 遍历父类的prototype内的所有方法,在子类的prototype中存放一个指向该方法的引用 for(methodName in parentClass.prototype){ //如果子类的prototype中存在同名方法,则该方法的引用不会被复制 if(!this.prototype[methodName]){ console.log('Copy the method '+methodName+' from class '+parentClassName); this.prototype[methodName] = parentClass.prototype[methodName]; } } } // 定义一个多亲继承子类,里面的name变量可接受外部访问 var MultiInheritance = function(name){ this.name = name; }; MultiInheritance.extend(Printable); // 将功能类Printable中的方法的引用复制到子类 MultiInheritance.extend(Clonable); // 将功能类Clonable中的方法的引用复制到子类 // 创建一个名为“Multi-Inheritance 1”的多亲继承子类 var multiInheritance1 = new MultiInheritance('Multi-Inheritance 1'); multiInheritance1.print(); multiInheritance1.clone(); // 创建一个名为“Multi-Inheritance 2”的多亲继承子类 var multiInheritance2 = new MultiInheritance('Multi-Inheritance 2'); multiInheritance2.print(); multiInheritance2.clone();
执行上述代码,浏览器控制台将输出如下信息:
Copy the method print from class Printable
Copy the method clone from class Clonable
The instance Multi-Inheritance 1 is printable!
The instance Multi-Inheritance 1 is clonable!
有2点需要注意:
1.在功能类Printable和Clonable的方法中,子类的公共变量能够被this关键字访问到。
2.在顶层对象Object的extend方法中,如果子类中存在和父类同名的方法,
根据“同名方法,子类优先”的原则,子类的方法不会被覆盖,而父类的方法也仍可被访问。