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日

相关文章

  • 微信小程序如何像vue一样在动态绑定类名

    在微信小程序中,可以使用类似于Vue.js的动态绑定类名的方式来渲染样式。下面,我将详细讲解如何在微信小程序中实现这个功能,并提供两个示例说明。 步骤一:在标签中使用动态类名 首先,在小程序的 wxml 中,在需要绑定类名的标签内部使用 class 属性。然后,使用{}包裹一个JavaScript 表达式来动态渲染类名。 例如,在下面的 wxml 中,我们动…

    other 2023年6月27日
    00
  • jq中的事件委托:closest parent parents delegate

    jq中的事件委托: closest parent parents delegate jQuery是一种流行的JavaScript库,简化了处理HTML文档、处理元素的方法和事件,其中事件委托是一个非常重要的概念。事件委托可以提高代码的性能,减少内存消耗,同时还可以处理动态创建的元素。jQuery提供了closest、parent、parents、delega…

    其他 2023年3月28日
    00
  • 斗鱼账号绑定手机号以后能解除绑定吗?

    当您在斗鱼上绑定您的手机号的时候,您需要通过验证码来进行验证,这是为了保证您的账号安全性。但一旦您的手机号码被绑定,想要解除绑定就需要了解一些操作步骤。 解除手机号绑定需要注意以下几点: 不能在解除绑定后24小时内重新绑定; 当前手机是否绑定了其他账号,如果是,则无法解除; 当前账号是否有被冻结或违反规定,若冻结或有违规行为,则无法解除; 解除绑定的手机号将…

    other 2023年6月27日
    00
  • nginx按天生成日志文件的简易配置

    nginx按天生成日志文件的简易配置 在Nginx的日志配置中,我们可以指定日志文件的存放位置及文件名称,以及日志记录的格式。但是默认情况下,日志文件是按照大小进行切分的,这样会导致较长时间内的日志集中在一个文件中,难以分析和查询。为了更好地管理日志文件,我们可以将日志文件按照时间进行切分,即每天生成一个新的日志文件。 配置步骤 在 nginx.conf 配…

    其他 2023年3月29日
    00
  • Mysql 8.0解压版下载安装以及配置的实例教程

    MySQL 8.0解压版下载安装以及配置的实例教程 本教程将详细介绍如何下载、安装和配置MySQL 8.0解压版。MySQL是一个流行的开源关系型数据库管理系统,提供了稳定可靠的数据存储和管理功能。 步骤1:下载MySQL 8.0解压版 首先,访问MySQL官方网站(https://www.mysql.com/)并导航到下载页面。在下载页面中,找到MySQL…

    other 2023年8月15日
    00
  • bash脚本编程学习之算术运算与文件查找

    Bash脚本编程学习之算术运算与文件查找攻略 算术运算 在Bash脚本编程中,我们可以使用内置的算术运算符来进行数值计算。以下是一些常用的算术运算符: +:加法 -:减法 *:乘法 /:除法 %:取余 下面是一个示例,演示如何在Bash脚本中进行算术运算: #!/bin/bash # 定义两个变量 num1=10 num2=5 # 加法运算 sum=$((n…

    other 2023年8月15日
    00
  • readystatechange事件

    readyStateChange事件 什么是readyStateChange事件? 在使用 Ajax 技术进行网络通信时,我们经常需要使用XMLHttpRequest对象。在这个对象中,readyState表示 XMLHttpRequest 对象的状态。而readystatechange事件则是在这个状态发生变化时被触发。 具体来说,当readyState属…

    其他 2023年3月29日
    00
  • HTML仿命令行界面具体实现

    HTML仿命令行界面可以使用HTML、CSS和JavaScript实现,下面我将分步骤介绍具体实现方法。 1. HTML布局 首先,我们需要准备一个HTML文件,其中需要定义一个输入框和一个显示框,可以使用一个div元素来充当整个界面,如下所示: <div class="terminal"> <div class=&qu…

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