javascript 中的继承实例详解

发布时间 - 2026-01-11 00:58:38    点击率:

javascript 中的继承实例详解

阅读目录

  • 原型链继承
  • 借用构造函数
  • 组合继承
  • 寄生组合式继承
  • 后记

继承有两种方式:接口继承和实现继承。接口继承只继承方法签名,而实现继承则继承实际的方法。

由于函数没有签名,在ECMAScript中无法实现接口继承。ECMAScript只支持实现继承,而且实现继承主要依靠原型链来实现。

下面介绍几种js的继承:

原型链继承

原型链继承实现的本质是重写原型对象,代之以一个新类型的实例。代码如下:

function SuperType() {
  this.property = true;
}

SuperType.prototype.getSuperValue = function() {
  return this.property;
};

function SubType() {
  this.subproperty = false;
}

// 继承了SuperType
SubType.prototype = new SuperType();

SubType.prototype.getSubValue = function () {
  return this.subproperty;
};

var instance = new SubType();

console.log(instance.getSuperValue()); // true

可以看到instance调用了父级的getSuperVlue()方法,实现了继承。

原型链的继承有如下问题:

  1. 包含引用类型值的原型时,在改变原型的引用类型时,会全部改了
  2. 在创建子类型的实例时,没有办法在不影响所有对象实例的情况下,给超类型的构造函数传递参数

示例代码如下:

function SuperType1() {
  this.colors = ['red', 'blue', 'green'];
}
function SubType1() {

}
SubType1.prototype = new SuperType1();
var instance1 = new SubType1();
instance1.colors.push('black');
console.log(instance1.colors); // [ 'red', 'blue', 'green', 'black' ]

var instance2 = new SubType1();
console.log(instance2.colors); // [ 'red', 'blue', 'green', 'black' ]

可以发现,instance1和instance2的colors属性是共享的,这就出问题了,同时也能够看出,在new一个新的方法时,如果传值的话,是传不到父级的。

借用构造函数

原理是在子类型构造函数的内部调用超类型构造函数,因为函数只不过是在特定环境中执行代码的对象,这样就可以获取父级的方法和属性了。

代码如下:

function SuperType(name) {
  this.name = name;
}

function SubType(name) {
  // 继承了SuperType,同时还传递了参数
  SuperType.call(this, name);

  // 实例属性
  this.age = 29;
}

var instance = new SubType('Bob');

console.log(instance.name); // Bob
console.log(instance.age); // 29

可以看出,调用构造函数继承解决了向父类型传参的问题,但调用构造函数也有其自身的问题:

  1. 方法都在构造函数中,函数复用没有了。
  2. 超类型的原型中定义的方法,对子类型而言是不可见的。

第一个问题很明显,针对第二个问题的解释是,由于只是执行了一次函数,并没有new出新对象,故而父类prototype中的方法对子类是不可见的。

组合继承

由于原型链继承和借用构造函数继承都有缺陷,故而在实际中一般不会单独使用。

组合继承是借用其两者的优点而产生的继承方法。

其原理是使用原型链实现对原型属性和方法的继承,通过借用构造函数来实现对实例属性的继承。

代码如下:

function SuperType(name) {
  this.name = name;
  this.colors = ['red', 'blue', 'green'];
}

SuperType.prototype.sayName = function() {
  console.log(this.name);
};

function SubType(name, age) {
  // 继承属性
  SuperType.call(this, name);

  this.age = age;
}
// 继承方法
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function() {
  console.log(this.age);
};

var instance1 = new SubType('Nicholas', 29);
instance1.colors.push('black');

console.log(instance1.colors); // [ 'red', 'blue', 'green', 'black' ]
instance1.sayName(); // Nicholas
instance1.sayAge(); // 29

var instance2 = new SubType('Greg', 27);

console.log(instance2.colors); // [ 'red', 'blue', 'green' ]
instance2.sayName(); // Greg
instance2.sayAge(); // 27

组合继承能够解决上面两种继承方式带来的问题,但是组合继承也有其自身的小问题,那就是会调用两次超类型构造函数,通过分析便可知道 一次是在创建子类型原型的时候,另一次是在子类型构造函数内部。

寄生组合式继承

寄生组合式继承的原理为通过借用构造函数来继承属性,通过原型链的混成形式来继承方法,基本思路是不必为了指定子类型的原型而调用超类型的构造函数,我们所需要的无非就是超类型原型的一个副本而已。

代码如下:

function object(o) {
  function F() {}
  F.prototype = o;
  return new F;
}

function inheritPrototype(subType, superType) {
  var prototype = object(superType.prototype);
  prototype.constructor = subType;
  subType.prototype = prototype;
}

function SuperType(name) {
  this.name = name;
  this.colors = ['red', 'blue', 'green'];
}

SuperType.prototype.sayName = function() {
 console.log(this.name);
};

function SubType(name, age) {
  SuperType.call(this, name);

  this.age = age;
}

// 继承的关键
inheritPrototype(SubType, SuperType);

SubType.prototype.sayAge = function() {
  console.log(this.age);
};

var instance = new SubType('天涯', 23);
instance.sayName();
instance.sayAge();

寄生组合式继承只有在调用构造函数时执行了一遍超类型,解决了组合继承的小问题。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


# javascript  # 中的继承  # js  # 继承  # 继承详解及实例  # js中继承的几种用法总结(apply  # call  # prototype)  # js的2种继承方式详解  # 不错的一篇关于javascript-prototype继承  # JavaScript是如何实现继承的(六种方式)  # 实现JavaScript中继承的三种方式  # 深入了解javascript中的prototype与继承  # JS继承--原型链继承和类式继承  # Extjs学习笔记之八 继承和事件基础  # 是在  # 也有  # 来实现  # 解决了  # 都有  # 都在  # 第一个  # 子类  # 两种  # 继承了  # 两次  # 一遍  # 这就  # 希望能  # 第二个  # 便可  # 可以看到  # 几种  # 重写  # 没有办法 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 如何在橙子建站中快速调整背景颜色?  Laravel如何使用查询构建器?(Query Builder高级用法)  瓜子二手车官方网站在线入口 瓜子二手车网页版官网通道入口  Laravel广播系统如何实现实时通信_Laravel Reverb与WebSockets实战教程  如何在宝塔面板中创建新站点?  详解vue.js组件化开发实践  Linux网络带宽限制_tc配置实践解析【教程】  西安市网站制作公司,哪个相亲网站比较好?西安比较好的相亲网站?  Laravel怎么返回JSON格式数据_Laravel API资源Response响应格式化【技巧】  Edge浏览器提示“由你的组织管理”怎么解决_去除浏览器托管提示【修复】  Android利用动画实现背景逐渐变暗  如何快速搭建安全的FTP站点?  Laravel如何创建自定义Facades?(详细步骤)  实例解析Array和String方法  Java解压缩zip - 解压缩多个文件或文件夹实例  Laravel如何集成Inertia.js与Vue/React?(安装配置)  新三国志曹操传主线渭水交兵攻略  Python文本处理实践_日志清洗解析【指导】  Laravel如何集成第三方登录_Laravel Socialite实现微信QQ微博登录  如何获取上海专业网站定制建站电话?  Laravel怎么实现API接口鉴权_Laravel Sanctum令牌生成与请求验证【教程】  如何获取PHP WAP自助建站系统源码?  Laravel如何与Vue.js集成_Laravel + Vue前后端分离项目搭建指南  Laravel集合Collection怎么用_Laravel集合常用函数详解  C++时间戳转换成日期时间的步骤和示例代码  Laravel如何使用Gate和Policy进行权限控制_Laravel权限判定与策略规则配置  教你用AI将一段旋律扩展成一首完整的曲子  Laravel如何使用Service Provider注册服务_Laravel服务提供者配置与加载  音响网站制作视频教程,隆霸音响官方网站?  phpredis提高消息队列的实时性方法(推荐)  宙斯浏览器视频悬浮窗怎么开启 边看视频边操作其他应用教程  如何在阿里云虚拟机上搭建网站?步骤解析与避坑指南  Internet Explorer官网直接进入 IE浏览器在线体验版网址  java ZXing生成二维码及条码实例分享  JavaScript如何实现类型判断_typeof和instanceof有什么区别  Laravel怎么使用Intervention Image库处理图片上传和缩放  利用vue写todolist单页应用  微信小程序 canvas开发实例及注意事项  Laravel如何配置中间件Middleware_Laravel自定义中间件拦截请求与权限校验【步骤】  Win11怎么恢复误删照片_Win11数据恢复工具使用【推荐】  Python面向对象测试方法_mock解析【教程】  🚀拖拽式CMS建站能否实现高效与个性化并存?  今日头条微视频如何找选题 今日头条微视频找选题技巧【指南】  微信小程序 配置文件详细介绍  Laravel怎么使用Session存储数据_Laravel会话管理与自定义驱动配置【详解】  独立制作一个网站多少钱,建立网站需要花多少钱?  Laravel模型关联查询教程_Laravel Eloquent一对多关联写法  Claude怎样写结构化提示词_Claude结构化提示词写法【教程】  javascript中的try catch异常捕获机制用法分析  如何在HTML表单中获取用户输入并结合JavaScript动态控制复利计算循环