JavaScript 五种常见继承模式详解与对比

作者:半夏

时间:2026-10-29

浏览:401

本文深入探讨 JavaScript 中五种核心继承模式。从基础的借用构造函数、组合继承,到 ES5 规范的原型式继承,再到优化私有方法的寄生式继承,最后重点解析解决组合继承缺陷的寄生组合式继承。通过对比各模式的优缺点及代码实现,帮助开发者理解原型机制并选择最佳继承方案。

文章目录

JavaScript 原型继承概述

严格来说,JavaScript 并非一门传统的面向对象语言,它未提供传统意义上的类继承机制,而是基于原型链实现继承。尽管关于 JavaScript 原型继承的讨论已非常普遍,但为了彻底厘清这一概念,本文重新梳理了《JavaScript 设计模式》中涉及的几种原型继承实现方式,重点介绍几种基础且常用的继承模式,欢迎读者提出不同见解。

最基础的原型链继承在此不再赘述,本文将重点阐述其他几种继承模式的具体实现与差异。

借用构造函数与组合继承

1. 借用构造函数继承(Constructor Borrowing)


function Father (name) {
this.name=name;
}
function Son (name) {
Father.call(this,name); //在子类型中调用超类型的构造函数
this.age=15;
}
var me=new Son("Su"); 

该模式的主要优势在于可以向子类型构造函数传递参数,例如图中所示的 name 属性传递。

其局限性在于:1. 方法必须在构造函数内部定义,导致无法实现方法复用;2. 超类型原型中定义的方法对子类型不可见,无法访问。

2. 组合继承(Combination Inheritance)


//超类型构造函数function Father (name) {
this.name=name;
this.famMember=[];
}//超类型构造函数原型方法
Father.prototype.sayName=function () {
alert(this.name);
}//子类型构造函数
function Son (name,age) {
Father.call(this,name); //构造函数方法
this.age=age;
}
Son.prototype=new Father(); //重写子类型原型对象
Son.prototype.constructor=Son; //重写构造函数属性指向子类型
Son.prototype.sayAge=function () {
alert(this.age);
} //重写原型对象后再加入方法
var me=new Son("Su",15);
me.famMember.push("dad","mom"); //子类型可以调用超类型构造函数内的方法var he=new Son("Li",14);alert(he.famMember); // [] 

这种模式结合了原型链和借用构造函数的优点,使得不同的子类既能拥有自己的实例属性,又能共享原型上的方法。

其缺点是需要调用两次超类型的构造函数,这会导致同名属性和方法在子类型原型上被覆盖一次,造成性能浪费。

原型式与寄生式继承

3. 原型式继承(Prototypal Inheritance)


function object (o) {
function F () {}
F.prototype=o;
return new F();
}var obj={}; //将obj对象传入作为新对象的原型。var me=object(obj); 

使用此模式继承时,必须存在一个作为原型的对象,因此所有继承自该原型的子类型所共享的属性与方法都是共用的。

ES5 标准通过新增 Object.create() 方法,从规范层面确立了原型式继承的实现方式。

4. 寄生式继承(Parasitic Inheritance)


function object (o) {
function F () {}
F.prototype=o;
return new F();
}
var obj={}; //将obj对象传入作为新对象的原型。到这里都与原型式继承相同function creObj(o) {  var clone=object(obj);  clone.sayHi=function () {    alert("Hi");  };return clone; }
var me=creObj(obj); 

该模式的优势在于弥补了原型式继承仅支持公有属性和方法的不足,允许子类型拥有私有属性和方法。

寄生组合式继承优化方案

5. 寄生组合式继承(Parasitic Combination Inheritance)


function inherit (father,son) {
var pro=Object(father.prototype); //创建超类型原型对象的副本
pro.constructor=son;
son.prototype=pro;           //将副本作为子类型的原型对象
} 

此方法旨在解决组合继承中因多次调用构造函数而导致的属性方法覆盖问题。

使用上图代码替代组合继承中的 Son.prototype=new Father(); 语句。这种方式仅需调用一次父类型的构造函数,避免了创建多余不必要的属性方法,同时保持了原型链的完整性,被视为一种理想的引用类型继承方案。

关于 JavaScript 继承模式的初步介绍至此结束,希望以上内容能对大家有所帮助,更多技术细节请持续关注本站后续更新。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章