JavaScript 继承机制的四种实现方式详解
本文详细解析 JavaScript 中实现继承的四种主要方式:对象冒充、利用 call 方法、原型链以及混合模式。通过具体代码示例,阐述如何利用构造函数和原型对象实现属性和方法的复用,并分析各方法的适用场景与注意事项,帮助开发者理解 JavaScript 宽松且灵活的继承机制。
JavaScript 继承机制概述
在掌握 JavaScript 类和对象的创建基础后,本文对 JavaScript 的继承机制进行总结。与 Java 严格明确的定义不同,JavaScript 的继承实现方式更为宽松,类似于其变量的使用风格。开发者可以设计自定义方法来“模仿”继承机制,主要包含以下几种实现路径:
对象冒充实现继承
1、对象冒充
<script type="text/javascript">
function classA(str){
this.str=str;
this.printstr=function(){
document.write(this.str);
document.write("<br>");
}
this.getstr=function(){
return this.str;
}
}
function classB(name,str){
//下面这两句代码相当于将classA代码体中的内容搬到这里
this.newMethod1=classA;
this.newMethod1(str);
//注意,这里的写法
delete this.newMethod1;
//新的方法和属性的定义须在删除了newMethod之后定义,因为可能覆盖超类的属性和方法。
this.name=name;
this.sayName=function(){
document.write(this.name);
document.write("<br>");
}
}
var a=new classB("Amy","helloworld");
a.printstr();
alert(a.getstr());
a.sayName();
</script>
在 function 定义的代码块中,代码体相当于一个类,其中包含 this 关键字。通过 this 可以为该类添加属性和方法。前述代码示例中包含以下两句关键逻辑:
this.newMethod1=classA; this.newMethod1(str);
在 classB 中定义了 newMethod1 变量,该变量是一个引用,指向 classA,并调用了 classA。这两行代码的作用等同于将 classA 代码块中的内容直接复制到 classB 中,因此创建的 classB 对象自然具备 classA 的属性和方法。此外,对象冒充还可以实现多继承,具体示例如下:
function ClassZ() {
this.newMethod = ClassX;
this.newMethod();
delete this.newMethod;
this.newMethod = ClassY;
this.newMethod();
delete this.newMethod;
}
需要注意的是,classY 会覆盖 classX 中同名的属性和方法。如果设计合理,classZ 不应继承具有相同属性和方法的不同类,以避免冲突。
利用 call 方法实现继承
2、利用 call() 方法
<script type="text/javascript">
function classA(str){
this.str=str;
this.printstr=function(){
document.write(this.str);
document.write("<br>");
}
this.getstr=function(){
return this.str;
}
}
function classB(name,str){
//利用call方法实现继承
classA.call(this,str);
this.name=name;
this.sayName=function(){
document.write(this.name);
document.write("<br>");
}
}
var a=new classB("Amy","helloworld");
a.printstr();
alert(a.getstr());
a.sayName();
</script>
call() 方法的第一个参数传递一个对象,此时 this 指向当前对象;后续参数(可能有多个)则是传递给调用 call() 方法的类(函数)所需的参数。classA.call() 同样相当于将 classA 代码块中的内容直接复制到这里,使得 classB 的对象可以直接使用 classB 中定义的变量和方法。
原型链实现继承
3、原型链
<script type="text/javascript">
function cA(){};
cA.prototype.name="John";
cA.prototype.sayName=function(){
document.write(this.name);
document.write("<br>");
}
function cB(){};
cB.prototype=new cA();
cB.prototype.age=23;
cB.prototype.sayAge=function(){
document.write(this.age);
document.write("<br>");
}
var objB=new cB();
objB.sayAge();
objB.sayName();
document.write("is objB the instance of cA "+(objB instanceof cA));
document.write("<br>");
document.write("is objB the instance of cB "+(objB instanceof cB));
document.write("<br>");
</script>
在此处定义类时需要使用 prototype 关键字,定义 function 时不带参数。prototype 后面的变量或方法类似于 Java 中被 static 修饰后的属性和方法,属于所有对象共有。这里有一个特殊之处:cB.prototype=new cA(); 该语句相当于将 cA 对象的内容复制给 cB,随后 cB 还可以追加自己的属性和方法。
混合模式实现继承
4、混合方法
<script type="text/javascript">
function cA(name){
this.name=name;
};
cA.prototype.sayName=function(){
document.write(this.name);
document.write("<br>");
}
function cB(name,age){
cA.call(this,name);
this.age=age;
};
cB.prototype=new cA();
cB.prototype.sayAge=function(){
document.write(this.age);
document.write("<br>");
}
var objB=new cB("Alan",27);
objB.sayName();
objB.sayAge();
document.write("is objB the instance of cA "+(objB instanceof cA));
document.write("<br>");
document.write("is objB the instance of cB "+(objB instanceof cB));
document.write("<br>");
</script>
这种方法可以将属性封装在类体内,而利用原型方式定义方法。个人觉得这是一种较好的设计模式,利用 prototype 定义的函数可以为多个对象重用。这里需要注意两点:cB 类体内有 cA.call(this,name); 同时还要将 cB 原型赋为 cB 对象,即:cB.prototype=new cA(); cA.call(this,name) 同样相当于将 cA 类块内的代码复制于此,后一句话又将 cA 的方法添加给 cB,同时 cB 还可以追加自己的属性和方法。
以上是本次对 JavaScript 继承机制的总结,不足之处望各位指正批评。
ES6模块化中js文件怎么用import和export交互
2026-11-05 17:00:48
JS读取本地文件时报错或无响应的常见原因
2026-11-05 16:32:31
let、const与var的区别:JavaScript变量声明最佳实践
2026-11-05 14:16:38
JS中直接定义静态二维数组的字面量写法
2026-11-05 14:16:08
JS 怎么查找字符串中所有匹配项的位置
2026-11-05 14:15:53
