JavaScript 面向对象继承模式详解:组合、原型、寄生与寄生组合式
本文深入解析 JavaScript 中的四种主要继承模式。首先介绍结合原型链与借用构造函数的组合继承,解决属性共享问题;接着阐述无需预定义构造函数即可实现浅复制的原型式继承;随后讲解通过增强对象解决效率问题的寄生式继承;最后重点分析集两者优点于一身、仅调用一次构造函数且保持原型链不变的寄生组合式继承,被公认为引用类型最理想的继承范式。
JavaScript 继承模式概述
本次内容将详细讲解组合继承、原型式继承、寄生式继承以及寄生组合式继承这几种实现方式。
组合继承原理与实现
1. 组合继承:也被称为伪经典继承,其核心思想是将原型链机制与借用构造函数技术结合起来使用的一种继承方案。
具体实现逻辑如下所示:
function SuperType(name) {
this.name = name;
this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function() {
alert(this.name);
}
function SubType(name, age) {
SuperType.call(this, name);
this.age = age;
}
//继承方法
SubType.prototype = new SuperType();
SubType.prototype.sayAge = function() {
alert(this.age);
}
var instance1 = new SubType("Nicholas", 29);
instance1.colors.push("black");
alert(instance1.colors); //red,blue,green,black
instance1.sayName(); //Nicholas
instance1.sayAge(); //29
var instance2 = new SubType("Greg", 27);
alert(instance2.colors); //red,blue,green
instance2.sayName(); //Greg
instance2.sayAge(); //27
组合继承方案成功规避了单纯使用原型链或借用构造函数时存在的缺陷,并融合了二者的优势。
原型式继承机制
2. 原型式继承
该方式允许在不预先定义构造函数的情况下完成继承操作,其底层原理是对指定对象执行浅层复制。此外,复制生成的副本对象还可以进行进一步的修改和扩展。
function object(o) {
function F(){};
F.prototype = o;
return new F;
}
var person = {
name: "Nicholas",
friends: ["Shelby", "Court", "Van"]
};
var antherPerson = object(person);
antherPerson.name = "Greg";
antherPerson.friends.push("Rob");
var antherPerson = object(person);
antherPerson.name = "Linda";
antherPerson.friends.push("Barbie");
alert(person.friends); //Shelby,Court,Van,Rob,Barbie
寄生式继承与优化
3. 寄生式继承
寄生式继承与原型式继承高度相似,同样基于特定对象或信息创建新对象,随后对对象进行增强处理并返回。为了克服组合继承模式中因多次调用超类型构造函数而导致的性能低下问题,可以将此模式与组合继承结合使用。
function object(o) {
function F(){};
F.prototype = o;
return new F;
}
function createAnother(original) {
var clone = object(original);
clone.sayHi = function() {
alert("Hi");
};
return clone;
}
var person = {
name: "Nicholas",
friends: ["Shelby", "Court", "Van"]
};
var anotherPerson = createAnother(person);
anotherPerson.sayHi();
寄生组合式继承优势
4. 寄生组合式继承
该模式集合了寄生式继承与组合继承的优点,是实现基本类型继承最高效的方法。
//继承原型
function extend(subType, superType) {
function F(){};
F.prototype = superType.prototype;
var prototype = new F;
prototype.constructor = subType;
subType.prototype = prototype;
}
//超类方法
function SuperType(name) {
this.name = name;
this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function() {
return this.name;
}
//子类方法
function SubType(name, age) {
SuperType.call(this, name);
this.age = age;
}
//继承超类的原型
extend(SubType, SuperType);
//子类方法
SubType.prototype.sayAge = function() {
return this.age;
}
var instance1 = new SubType("Shelby");
var instance2 = new SubType("Court", 28);
instance1.colors.push('black');
alert(instance1.colors); //red,blue,green,black
alert(instance2.colors); //red,blue,green
alert(instance1 instanceof SubType); //true
alert(instance1 instanceof SuperType); //true
该示例的高效性体现在仅调用了一次 SuperType 构造函数,从而避免了在 SubType.prototype 上创建多余且不必要的属性。同时,原型链结构得以保持完整,因此 instanceof 和 isPrototypeOf() 方法仍能正常使用。业界普遍认为,寄生组合式继承是处理引用类型最理想的继承范式。
以上关于 JS 面向对象继承多种组合方式的详解内容分享完毕,希望能为读者提供参考,并欢迎大家继续支持本站。
D3.js 比例尺与坐标轴的配置详解
2026-11-05 16:54:46
JavaScript怎么遍历对象的Symbol键和不可枚举属性
2026-11-05 13:13:39
封装一个健壮的JS字符串判空工具函数
2026-11-05 12:16:14
JavaScript合并数组的三种常用方法:concat、扩展运算符与push
2026-11-05 11:22:29
JavaScript立即执行函数(IIFE)是什么及基本语法
2026-11-05 10:51:19
