夯基础之手撕javascript继承详解

夯基础之手撕JavaScript继承详解

本文将介绍JavaScript中继承的几种实现方式,并通过手写代码的方式,从底层原理上详解每种实现方式的具体过程。

一、JavaScript中继承的实现方式

1. 原型链继承

通过将子类的原型指向父类实例来实现继承。

function Parent() {}
function Child() {}
Child.prototype = new Parent();

原型链继承的缺点在于:
- Child实例的所有属性和方法都会被继承,包括无意义的父类属性。
- 当Child的实例修改继承属性时,会影响到原型链上的所有实例。

2. 构造函数继承

在子类中通过调用父类的构造函数来获取父类实例上的属性和方法,同时将父类属性和方法绑定到子类的实例上。

function Parent() {
  this.name = 'parent';
}
function Child() {
  Parent.call(this);
  this.age = 18;
}

构造函数继承的缺点在于:
- 每次创建的子类实例都会创建一份父类实例上的属性和方法。
- 无法继承父类原型上的属性和方法。

3. 组合继承

将原型链继承和构造函数继承结合起来,通过父类构造函数绑定属性和方法到子类实例上,通过子类原型继承父类原型上的属性和方法来实现继承。

function Parent() {
  this.name = 'parent';
}
Parent.prototype.sayName = function () {
  console.log(this.name);
}
function Child() {
  Parent.call(this);
  this.age = 18;
}
Child.prototype = new Parent();

组合继承的缺点在于:
- 在使用new关键字创建Child实例时,会调用2次父类构造函数,导致子类实例上出现了两份相同的属性和方法。

4. 原型式继承

通过借助已有对象的能力来创建新对象,类似于JavaScript中的浅拷贝。

let person = {
  name: 'Tom',
  friends: ['Jerry', 'Bob']
};
let anotherPerson = Object.create(person);

原型式继承的缺点在于:
- 会存在有意义或无意义的共享引用问题。
- 无法进行属性和方法的复用。

5. 寄生式继承

在工厂模式或构造函数模式的基础上,在函数内部创建一个仅用于封装继承过程的函数,最终返回这个新函数,从而达到对原型式继承对进一步封装的效果。

function object(o) {
  function F(){}
  F.prototype = o;
  return new F()
}
function createAnother(original) {
  let clone = object(original);
  clone.sayHi = function() {
    console.log('hi');
  }
  return clone;
}
let person = {
  name: 'Tom',
  friends: ['Jerry', 'Bob']
};
let anotherPerson = createAnother(person);

寄生式继承的缺点在于:
- 无法进行属性和方法的复用。
- 与构造函数模式一样,每次创建实例都会创建一份方法。

6. 寄生组合式继承

通过组合继承和寄生式继承的方式来实现继承,避免了组合继承父类构造函数被多次调用和寄生式继承无法进行属性和方法复用的缺点。

function inheritPrototype(SubType, SuperType) {
  let prototype = Object.create(SuperType.prototype);
  prototype.constructor = SubType;
  SubType.prototype = prototype;
}
function Parent() {
  this.name = 'parent';
}
Parent.prototype.sayName = function() {
  console.log(this.name);
}
function Child() {
  Parent.call(this);
  this.age = 18;
}
inheritPrototype(Child, Parent);

二、示例说明

1. 原型链继承示例

function Animal() {
  this.legsNum = 4;
}
function Cat() {}
Cat.prototype = new Animal();
let cat = new Cat();
console.log(cat.legsNum);  // 4

通过将Cat的原型指向一个Animal实例,实现了Cat对Animal实例属性和方法的继承。

2. 寄生组合式继承示例

function Mammal(name) {
  this.name = name;
}
Mammal.prototype.sayName = function() {
  console.log(this.name);
}
function Dog(name, age) {
  Mammal.call(this, name);
  this.age = age;
}
inheritPrototype(Dog, Mammal);
Dog.prototype.sayAge = function() {
  console.log(this.age);
}
let dog = new Dog('小黑', 3);
dog.sayName();  // 小黑
dog.sayAge();  // 3

通过将Mammal构造函数中的属性和方法绑定到Dog实例上,并通过寄生式继承Mammal的原型属性和方法到Dog的原型上,实现了对Mammal的构造函数和原型上的属性和方法进行了复用,同时达到了继承的目的。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:夯基础之手撕javascript继承详解 - Python技术站

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

相关文章

  • springboot连接oracle

    在Spring Boot应用程序中连接Oracle数据库是一个常见的需求。本文将介绍如何在Spring Boot应用程序中连接Oracle数据库,包括如何配置数据源、如何使用JdbcTemplateSQL查询等。 配置数据源 要连接Oracle数据库,我们需要在Spring Boot应用程序中配置数据源。以下是一个示例配置: spring.datasourc…

    other 2023年5月7日
    00
  • Java日志软件Log4j的基本使用教程

    Java日志软件Log4j的基本使用教程 Log4j是一个流行的Java日志记录工具,它可以帮助开发人员在应用程序中实现灵活的日志记录功能。本教程将详细介绍Log4j的基本使用方法,并提供两个示例说明。 步骤1:添加Log4j依赖 首先,您需要在您的Java项目中添加Log4j的依赖。您可以通过Maven或Gradle等构建工具来完成此操作。以下是使用Mav…

    other 2023年9月6日
    00
  • github上排名前100的android开源库介绍

    以下是详细讲解“GitHub上排名前100的Android开源库介绍”的完整攻略,过程中至少包含两条示例说明的标准Markdown格式文本: GitHub上排名前100的Android开源库介绍 GitHub是全球最大的开源社区,其中包含了大量的Android开源库。本文将介绍GitHub上排名前100的Android开源库,以及它们的主要功能和用途。 1.…

    other 2023年5月10日
    00
  • Jmeter如何基于命令行运行jmx脚本

    要基于命令行运行JMeter的JMX脚本,需要使用以下步骤: 进入JMeter的bin目录:cd apache-jmeter-x.x.x/bin/(这里的x.x.x代表的是JMeter的版本号) 使用以下命令运行JMX脚本:./jmeter -n -t [testplan.jmx] -l [testresult.jtl]其中,[testplan.jmx]是需…

    other 2023年6月26日
    00
  • android布局——单复选框(今天上课的内容总结下)

    Android布局——单复选框 单复选框是Android布局中经常使用的UI组件,它们可以让用户选择或确定某些选项,进而影响App的行为。在本篇文章中,我们将详细介绍单复选框的使用方法及布局技巧。 单选框 单选框(RadioButton)是一组互斥的选项,用户只能选择其中的一项。单选框通过RadioGroup容器进行布局,RadioGroup容器内的Radi…

    其他 2023年3月28日
    00
  • 浅谈C语言中include””与include<>的区别

    浅谈C语言中include””与include<>的区别 在C语言中,程序员通过使用头文件来引入函数、结构体等定义。头文件可以使用两种方式引入,一种是使用双引号””括起来的头文件名称,另一种是使用尖括号<>括起来的头文件名称。本文将会详细讲解这两种引入方式的区别和使用场景。 include””的使用 使用双引号””括起来的头文件名称是…

    other 2023年6月26日
    00
  • Android修改jar文件包名的方法分享

    Android修改jar文件包名的方法分享 在Android开发中,有时候我们需要修改一个已有的jar文件的包名。下面是一种常用的方法来实现这个目标。 步骤一:解压jar文件 首先,我们需要将jar文件解压缩到一个临时目录中。可以使用以下命令来完成这个步骤: unzip your_jar_file.jar -d temp_directory 这将会将jar文…

    other 2023年9月7日
    00
  • 百度网盘下载文件提示”系统限制,无法下载”的解决方法

    标题:解决百度网盘下载文件提示”系统限制,无法下载”的方法 在使用百度网盘下载文件的过程中,有时会出现“系统限制,无法下载”的提示,这是因为百度网盘为了保护用户的数据安全,设置了一些下载限制。下面介绍几种解决此问题的方法: 方法一:更换IP地址 可能是由于你的IP地址被限制了下载,导致出现下载限制,因此可以通过更换IP地址的方法来解决这个问题。 1.使用网络…

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