JavaScript 继承机制的 5 种实现方式详解
本文详细解析 JavaScript 中实现继承的五种核心方式:对象冒充、call() 方法、apply() 方法、原型链以及混合模式。通过具体代码示例,对比各方法的原理、适用场景及注意事项,帮助开发者理解 ECMAScript 中类与实例关系的构建逻辑,掌握不同继承模式的实现细节与差异。
JavaScript 继承机制概述
继承作为面向对象编程的核心特性,允许一个类复用另一个类的方法和属性。在 JavaScript 中,实现继承主要有五种方式:对象冒充、call() 方法、apply() 方法、原型链以及混合模式。
接下来将逐一介绍这几种实现方式的具体原理与用法。
对象冒充
对象冒充实现继承
对象冒充的原理是利用构造函数中的 this 关键字进行属性和方法的赋值。由于构造函数本质上是一个普通函数,我们可以将 ClassA 的构造函数绑定到 ClassB 上并执行,从而使 ClassB 获得 ClassA 构造函数中定义的属性和方法。
具体实现示例如下:
代码如下:
function ClassA(sColor){
this.color=sColor;
this.sayColor=function(){
alert(this.color);
}
}
function ClassB(sColor,sName){
this.newMethod=ClassA;
this.newMethod(sColor);
delete this.newMethod;
this.name=sName;
this.sayName=function(){
alert(this.name);
}
} 调用示例如下:
代码如下:
var objb=new ClassB("blue","Test");
objb.sayColor();//
blueobjb.sayName(); // Test 需要注意的是,必须删除对 ClassA 的引用(delete this.newMethod),否则后续定义的新方法和属性可能会覆盖超类的相应属性和方法。此外,这种机制支持多重继承的实现。
call()方法
call() 方法实现继承
随着对象冒充的普及,ECMAScript 第三版在 Function 对象中引入了 call() 和 apply() 两个新方法,用于实现类似的功能。
call() 方法的第一个参数指定函数执行时的 this 对象,其余参数则直接传递给函数本身。示例如下:
代码如下:
function sayColor(sPrefix,sSuffix){
alert(sPrefix+this.color+sSuffix);
}
var obj=new Object();
obj.color="red";
//output The color is red, a very nice color indeed.
sayColor.call(obj,"The color is ",", a very nice color indeed."); 若使用此方法实现继承,只需将前三行的赋值、调用和删除代码替换为以下代码:
代码如下:
function ClassB(sColor,sName){
//this.newMethod=ClassA;
//this.newMethod(sColor);
//delete this.newMethod;
ClassA.call(this,sColor);
this.name=sName;
this.sayName=function(){
alert(this.name);
}
} apply()方法
apply() 方法实现继承
apply() 方法与 call() 类似,区别在于第二个参数的传递形式。在 apply() 中,参数以数组形式传递。示例如下:
代码如下:
function sayColor(sPrefix,sSuffix){
alert(sPrefix+this.color+sSuffix);
}
var obj=new Object();
obj.color="red";
//output The color is red, a very nice color indeed.
sayColor.apply(obj,new Array("The color is ",", a very nice color indeed.")); 若使用此方法实现继承,只需将前三行的赋值、调用和删除代码替换为以下代码:
代码如下:
function ClassB(sColor,sName){
//this.newMethod=ClassA;
//this.newMethod(sColor);
//delete this.newMethod;
ClassA.apply(this,new Array(sColor));
this.name=sName;
this.sayName=function(){
alert(this.name);
}
} 与 call() 略有不同,如果超类的参数顺序与子类完全一致,apply() 的第二个参数可以直接使用 arguments 对象。
原型链
原型链实现继承
原型链继承在 ECMAScript 中原本就是基于原型对象设计的。原型对象上的任何属性和方法都会传递给该类的所有实例,利用这一特性即可实现继承机制。
使用原型链实现继承的示例如下:
代码如下:
function ClassA(){
}
ClassA.prototype.color="red";
ClassA.prototype.sayColor=function(){
alert(this.color);
};
function ClassB(){
}
ClassB.prototype=new ClassA(); 需要注意的是,调用 ClassA 构造函数时不传递参数。这是原型链继承的标准做法,需确保构造函数不接受任何参数。
混合方式
混合模式实现继承
混合模式结合了对象冒充和原型链两种方式的优点。示例如下:
代码如下:
function ClassA(sColor){
this.color=sColor;
}
ClassA.prototype.sayColor=function(){
alert(this.color);
}
function ClassB(sColor,sName){
ClassA.call(this,sColor);
this.name=sName;
}
ClassB.prototype=new ClassA();
ClassB.prototype.sayName=function(){
alert(this.name);
} 调用示例如下:
代码如下:
var objb=new ClassB("red","test");
objb.sayColor();// output red
objb.sayName();// output test作者:Artwl
JS合并多个数组的三种方法:concat、spread与flat
2026-11-05 17:39:45
JavaScript怎么准确判断数据类型:typeof、instanceof与Object.prototype.toString
2026-11-05 17:09:21
JS中将数组和对象混合组装为JSON字符串
2026-11-05 16:41:42
JS运算符优先级与结合性的区别是什么?
2026-11-05 13:22:02
JS Map怎么只遍历Key或Value
2026-11-05 13:00:36
