JavaScript 继承机制详解:原型链与 call/apply 实现对比

作者:函数茶馆

时间:2026-10-22

浏览:158

本文详细解析 JavaScript 中两种常见的继承实现方式:原型继承与 call/apply 继承。通过代码示例对比发现,原型继承可完整继承父类属性和方法,但存在引用共享问题;而 call/apply 方式仅能借用构造函数实现属性继承,无法继承 prototype 上的方法。文章总结了各自的适用场景及局限性,帮助开发者根据实际需求选择合适的继承策略。

文章目录

JavaScript 继承机制概述

本文通过具体实例深入解析 JavaScript 中实现继承的多种技术手段,旨在为开发者提供清晰的参考与指导。


var animal=function(name){ //构造函数
  this.name=name;
  this.sayhello=function(){
  alert("hi我是"+this.name);
  };
}
animal.prototype.shout=function(){ //prototype主要作用:给类增加一个新的属性或函数
  alert(this.name+"正在叫!");
};
animal.prototype.game=function(){
  alert(this.name+"正在玩耍!");
};
var dog=new animal("小黑");  //实例化
dog.sayhello();
dog.shout();
dog.game();

原型继承实现详解

一、原型继承机制


var animal=function(name){
  this.name=name;
  this.sayhello=function(){
  alert("hi我是"+this.name);
  };
}
animal.prototype.shout=function(){
  alert(this.name+"正在叫!");
};
animal.prototype.game=function(){
  alert(this.name+"正在玩耍!");
};
var Dog=function(name){
  this.name=name;
  this.shout=function(){   //重写父类的函数
  alert(this.name+"汪汪叫!");
  }
}
Dog.prototype=Cat.prototype=new animal();
var dog=new Dog("小黑");
dog.sayhello();
dog.shout();
dog.game();
var cat=new Cat("小白");
cat.sayhello();
cat.shout();
cat.game();

在原型继承模式中,animal 作为父类(或称为超类),子类通过关联该父类来实现继承关系。

为了优化代码结构,可以封装一个专用函数来统一处理继承逻辑。


var animal=function(name){
  this.name=name;
  this.sayhello=function(){
  alert("hi我是"+this.name);
  };
}
Function.prototype.extends=function(superclass){      //extends是保留关键字,不能拿出来单独使用,如var extends=function(){},而这里可以使用是因为他做为函数的属性添加上去
  this.prototype=new superclass();
};
animal.prototype.shout=function(){
  alert(this.name+"正在叫!");
};
animal.prototype.game=function(){
  alert(this.name+"正在玩耍!");
};
var Dog=function(name){
  this.name=name;
  this.shout=function(){
  alert(this.name+"汪汪叫!");
  }
}
Dog.extends(animal);
var dog=new Dog("小黑");
dog.sayhello();
dog.shout();
dog.game();
var dog=new Dog("小白");
dog.sayhello();
dog.shout();
dog.game();

call 与 apply 继承方式分析

二、利用 call 和 apply 实现继承(局限性分析)


var animal=function(name){
  this.name=name;
  this.sayhello=function(){
  alert("hi我是"+this.name);
  };
}
animal.prototype.shout=function(){
  alert(this.name+"正在叫!");
};
animal.prototype.game=function(){
  alert(this.name+"正在玩耍!");
};
var Dog=function(name){
  animal.call(this,name);
}
var dog=new Dog("小黑");
dog.sayhello();
dog.shout();
dog.game();

执行上述代码后,控制台输出结果为:hi我是小黑。

若尝试调用未正确继承的方法,系统将报错:TypeError: dog.shout is not a function。

使用 call 或 apply 方法仅能改变函数执行时的 this 指向,而无法直接继承通过 prototype 添加的方法。

总结而言,call 和 apply 继承方式适用于那些没有 prototype 属性,或者不需要继承 prototype 中定义的属性与函数的类。这是因为 call 和 apply 仅实现了方法的借用替换,并未执行对象属性和函数的深层复制操作。

相比之下,原型继承机制能够完整地继承父类的所有属性和函数。

需要注意的是,若子类中定义了与父类同名的属性,必须删除子类的原有属性,才能访问到继承自父类的属性值。

如需进一步了解 JavaScript 相关知识,可参考本站系列教程:《javascript面向对象入门教程》、《JavaScript中json操作技巧总结》、《JavaScript切换特效与技巧总结》、《JavaScript查找算法技巧总结》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》。

希望本文的阐述能对您的 JavaScript 程序设计工作提供实质性帮助。

实用工具推荐

电子包浆

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

使用 ›
图片压缩

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

使用 ›
相关文章