JavaScript继承模式粗探

JavaScript继承模式粗探

在 JavaScript 中实现继承的方式有很多,本文将介绍五种不同的继承模式,并通过示例代码进行说明和比较。

1. 原型链继承

原型链继承是最常见的一种继承方式,其基本思想是通过将子类的原型设为父类的实例实现继承。

function Parent() {
  this.name = 'parent';
  this.say = function() {
    console.log('Hello, I am ' + this.name);
  }
}

Parent.prototype.show = function() {
  console.log('show in parent');
}

function Child() {}

Child.prototype = new Parent(); // 子类的原型设为父类的实例

const child = new Child();
console.log(child.name); // parent
console.log(child.show()); // "show in parent"
console.log(child.say()); // "Hello, I am parent"

但是原型链继承有一个致命的缺陷,即父类的引用属性会被所有子类实例共享,容易导致修改一个子类实例的引用属性时,其他实例的引用属性也会跟着改变。

2. 借用构造函数继承

借用构造函数继承是通过调用父类的构造函数来实现继承。

function Parent(name) {
  this.name = name;
  this.say = function() {
    console.log('Hello, I am ' + this.name);
  }
}

function Child(name) {
  Parent.call(this, name); // 在子类构造函数中调用父类构造函数
}

const child1 = new Child('child1');
const child2 = new Child('child2');
console.log(child1.say()); // "Hello, I am child1"
console.log(child2.say()); // "Hello, I am child2"

但是借用构造函数继承的缺点是无法继承父类原型上的方法和属性。

3. 组合继承

组合继承是将原型链继承和借用构造函数继承结合起来,既能继承父类构造函数中的属性,又能继承父类原型上的方法。

function Parent(name) {
  this.name = name;
  this.say = function() {
    console.log('Hello, I am ' + this.name);
  }
}

Parent.prototype.show = function() {
  console.log('show in parent');
}

function Child(name) {
  Parent.call(this, name);
}

Child.prototype = new Parent(); // 将子类的原型设为父类的实例
Child.prototype.constructor = Child; // 修正constructor

const child = new Child('child');
console.log(child.name); // child
console.log(child.show()); // "show in parent"
console.log(child.say()); // "Hello, I am child"

可以看到,组合继承综合了原型链继承和借用构造函数继承的优点,但是存在一个缺点就是在使用子类生成对象时,调用了两次父类构造函数,第一次是在将子类原型指向父类实例时,第二次是在子类构造函数中。

4. 原型式继承

原型式继承是基于某个对象创建一个副本作为新对象的原型,然后扩展新对象,从而实现继承。

const parent = {
  name: 'parent',
  say: function() {
    console.log('Hello, I am ' + this.name);
  }
}

const child = Object.create(parent); // 基于parent创建child的原型
child.name = 'child';

console.log(child.say()); // "Hello, I am child"

但是原型式继承也存在跟原型链继承相同的问题,即引用类型的属性会被所有实例共享。

5. 寄生式继承

寄生式继承是在原型式继承的基础上,将扩展对象的过程封装在函数中,返回新对象。

const parent = {
  name: 'parent',
  say: function() {
    console.log('Hello, I am ' + this.name);
  }
}

function createChild(obj, name) {
  const child = Object.create(obj);
  child.name = name;
  return child;
}

const child = createChild(parent, 'child');
console.log(child.say()); // "Hello, I am child"

总结

前面介绍了五种 JavaScript 继承模式,每种继承方式都有其优缺点,可以根据具体场景选择不同的继承方式,实现对象的多态。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript继承模式粗探 - Python技术站

(0)
上一篇 2023年6月26日
下一篇 2023年6月26日

相关文章

  • 实例详解android studio如何导入.so文件的方法

    以下是关于Android Studio如何导入.so文件的方法的完整攻略: 在项目的src/main/jniLibs目录下创建对应的CPU架构文件夹(如armeabi-v7a、arm64-v8a等)。 将.so文件复制到对应的CPU架构文件夹中。 示例说明1:导入armeabi-v7a架构的.so文件 项目结构: – app – src – main – j…

    other 2023年10月14日
    00
  • win8系统使用360浏览器浏览网页提示此网站的某个加载项运行失败的原因及解决方法

    问题描述: 在win8系统下使用360浏览器浏览网页时可能会遇到提示“此网站的某个加载项运行失败”的问题,这种情况下会导致部分网页无法正常加载。那么,这个问题的原因是什么,如何解决呢? 解决步骤: Step 1:检查360浏览器及其插件是否最新版本 首先需要确保你的360浏览器及其插件是最新版本。在360浏览器的设置界面中,可以找到“插件管理”选项,在这里可…

    other 2023年6月25日
    00
  • 关于python:b64解码问题

    以下是关于“关于python:b64解码问题”的完整攻略,包含两个示例。 关于python:b64解码问题 在Python中,我们可以使用base64库对字符串进行编码和解码。但是,在解码时可能会遇到一些问题。以下是关于如何解决b64解码问题的详细攻略。 1. 解码 在解码时,我们可能会遇到解码错误的情况。以下是一个示例: import base64 # 解…

    other 2023年5月9日
    00
  • Wine更新3.5开发者版本:持RSA和ECDSA加密密钥(附下载地址)

    Wine更新3.5开发者版本: 持RSA和ECDSA加密密钥 最近,Wine开发者发布了Wine 3.5的更新版本,其中包含了新的加密算法,支持使用RSA和ECDSA加密密钥。这些算法的添加使得Wine更加安全和可靠,特别是对于那些需要与远程服务器通信的应用程序。 下载和安装Wine 3.5更新版本 要下载Wine 3.5更新版本,首先需要访问Wine官方网…

    other 2023年6月26日
    00
  • 在Python中使用gRPC的方法示例

    那么让我们开始“在Python中使用gRPC的方法示例”的完整攻略。 什么是gRPC gRPC是一个快速、高效、开源和通用的远程过程调用(RPC)框架。它最初由Google开发,支持多种编程语言。 gRPC使用ProtoBuf作为默认的数据序列化机制,这使得它可以高效地跨语言和平台之间进行通信。 gRPC的工作原理 gRPC使用Protocol Buffer…

    other 2023年6月27日
    00
  • centos7几种修改系统时区的方法

    CentOS7几种修改系统时区的方法 对于使用CentOS7的用户来说,时区的设置是非常重要的。因为系统时间是非常重要的,各种应用程序或是系统都依赖它来执行定时任务、日志记录以及其他类似的操作。在默认情况下,CentOS7的时区设置为UTC(协调世界时),这可能会给用户带来许多麻烦。 在本文中,我们将介绍几种修改CentOS7系统时区的方法。以帮助你更好地管…

    其他 2023年3月28日
    00
  • 给力Windows XP如何添加“管理员取得所有权”右键菜单

    这里是添加“管理员取得所有权”右键菜单的完整攻略: 1. 打开注册表编辑器 在 Windows XP 中,打开注册表编辑器的方法为:点击”开始”,选择”运行”,输入”regedit”并回车。这将打开注册表编辑器界面。 2. 定位注册表项 在注册表编辑器打开后,依次展开以下目录: HKEY_CLASSES_ROOT\*\shell 在 shell 目录下新建一…

    other 2023年6月27日
    00
  • 21.linux-写usb键盘驱动(详解)

    以下是关于“21.linux-写usb键盘驱动(详解)”的完整攻略: 写USB键盘驱动的基本步骤 写USB键盘驱动的基本步骤如下: 注册USB驱动。 实现probe函数,用于检测设备是否为USB键盘。 实现disconnect函数,用于断开设备连接。 实现read,用于读取键盘输入数据。 实现write函数,用于向键盘发送数据。 实现ioctl函数,用于处理…

    other 2023年5月9日
    00
合作推广
合作推广
分享本页
返回顶部