[js高手之路]寄生组合式继承的优势详解
本文详解JavaScript中寄生组合式继承的实现原理与优势。针对传统组合继承中父类构造函数被调用两次导致的性能损耗问题,介绍如何通过借用构造函数复制属性与寄生式继承获取原型方法相结合,实现高效且精准的原型链继承,避免实例化父类构造函数的冗余操作。
组合继承的缺陷分析
在前面的JavaScript面向对象系列文章中,我们已经深入探讨了组合继承与寄生继承两种模式。现在回顾一下组合继承的核心机制:
function Person( uName ){
this.skills = [ 'php', 'javascript' ];
this.userName = uName;
}
Person.prototype.showUserName = function(){
return this.userName;
}
function Teacher ( uName ){
Person.call( this, uName );
}
Teacher.prototype = new Person();
var oT1 = new Teacher( 'ghostwu' );
oT1.skills.push( 'linux' );
var oT2 = new Teacher( 'ghostwu' );
console.log( oT2.skills ); //php,javascript
console.log( oT2.showUserName() ); //ghostwu
组合继承模式存在一个明显的缺陷,即父类的构造函数会被执行两次。
第一次调用发生在第11行,当设置子类原型对象(prototype)时触发。
第二次调用发生在第9行,在创建子类实例的过程中再次触发。
寄生组合式继承的实现思路
构造函数的主要职责是复制实例属性,因此第9行的调用是不可省略的。而第11行的调用旨在获取父类原型对象上的方法。基于这一目的,是否存在其他更优的实现方式?
我们能否在无需实例化父类构造函数的情况下,依然获取到父类原型对象上的方法?答案是肯定的,我们可以利用寄生式继承来获取父类原型对象上的方法。
function Person( uName ){
this.skills = [ 'php', 'javascript' ];
this.userName = uName;
}
Person.prototype.showUserName = function(){
return this.userName;
}
function Teacher ( uName ){
Person.call( this, uName );
}
function object( o ){
var G = function(){};
G.prototype = o;
return new G();
}
function inheritPrototype( subObj, superObj ){
var proObj = object( superObj.prototype ); //复制父类superObj的原型对象
proObj.constructor = subObj; //constructor指向子类构造函数
subObj.prototype = proObj; //再把这个对象给子类的原型对象
}
inheritPrototype( Teacher, Person );
var oT1 = new Teacher( 'ghostwu' );
oT1.skills.push( 'linux' );
var oT2 = new Teacher( 'ghostwu' );
console.log( oT2.skills ); //php,javascript
console.log( oT2.showUserName() ); //ghostwu
寄生组合式继承的核心本质
简而言之,寄生组合式继承的本质是:借用构造函数用于属性复制,配合类似浅拷贝的方式处理父类原型对象。
以上关于寄生组合式继承优势的详解内容,希望能为读者提供参考,感谢支持。
JavaScript闭包与类(Class)的区别及适用场景对比
2026-11-05 15:48:57
JavaScript入门要学ES6吗?let与箭头函数等新特性解析
2026-11-05 14:49:16
JavaScript 8种数据类型详解:基本类型与引用类型的区别
2026-11-05 14:25:15
怎么在JavaScript中使用async/await优化Ajax异步流程
2026-11-05 13:56:15
JavaScript replace回调函数实现动态正则替换逻辑
2026-11-05 13:52:13
