JavaScript实现继承的6种常用方式总结

JavaScript实现继承的6种常用方式总结

本文主要介绍JavaScript实现继承的6种常用方式,包括原型链继承、构造函数继承、组合继承、寄生组合继承、ES6 class继承、Mixin继承。

1. 原型链继承

原型链继承是将子类的原型设置为父类的实例,通过原型链来实现继承。其实现步骤如下:

function Parent() {
  this.name = 'parent';
}

Parent.prototype.sayHello = function() {
  console.log('Hello from ' + this.name);
}

function Child() {}

Child.prototype = new Parent();

var child = new Child();
child.sayHello();

这种方式的缺陷是:所有子类实例共用一个父类实例,当修改某个子类实例中的属性时,其他子类实例的属性也会被修改。

2. 构造函数继承

构造函数继承是将父类的构造函数在子类中执行一遍,从而实现继承。其实现步骤如下:

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

Parent.prototype.sayHello = function() {
  console.log('Hello from ' + this.name);
}

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

var child = new Child('child');
child.sayHello();

这种方式的缺陷是:父类原型中的方法对于子类而言是不可见的。

3. 组合继承

组合继承是将原型链继承和构造函数继承结合起来,实现同时继承父类构造函数属性和原型上的方法。其实现步骤如下:

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

Parent.prototype.sayHello = function() {
  console.log('Hello from ' + this.name);
}

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

Child.prototype = new Parent();

var child = new Child('child');
child.sayHello();

这种方式的缺陷是:在调用两次父类构造函数,存在性能问题。

4. 寄生组合继承

寄生组合继承是在组合继承的基础上,通过优化避免了调用两次父类构造函数,其实现步骤如下:

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

Parent.prototype.sayHello = function() {
  console.log('Hello from ' + this.name);
}

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

Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;

var child = new Child('child');
child.sayHello();

这种方式是目前使用最多的继承方式,常用于大型项目中。

5. ES6 class继承

ES6 class继承是通过class和extends关键字实现继承,其实现步骤如下:

class Parent {
  constructor(name) {
    this.name = name;
  }

  sayHello() {
    console.log('Hello from ' + this.name);
  }
}

class Child extends Parent {
  constructor(name) {
    super(name);
  }
}

var child = new Child('child');
child.sayHello();

逐渐取代了以前传统的继承方式,被广泛使用。

6. Mixin继承

Mixin继承是通过将多个对象混合在一起,实现继承。其实现步骤如下:

function mix(...mixins) {
  class Mixin {
    constructor() {
      for (let mixin of mixins) {
        copyProperties(this, new mixin());
      }
    }
  }

  for (let mixin of mixins) {
    copyProperties(Mixin, mixin);
    copyProperties(Mixin.prototype, mixin.prototype);
  }

  return Mixin;
}

function copyProperties(target, source) {
  for (let key of Reflect.ownKeys(source)) {
    if (key !== "constructor"
      && key !== "prototype"
      && key !== "name") {
      let des = Object.getOwnPropertyDescriptor(source, key);
      Object.defineProperty(target, key, des);
    } 
  }
}

class Parent {
  constructor(name) {
    this.name = name;
  }

  sayHello() {
    console.log('Hello from ' + this.name);
  }
}

class Child extends mix(Parent) {
  constructor(name) {
    super(name);
  }
}

var child = new Child('child');
child.sayHello();

这种方式适用于需要组合多个对象的项目中。

示例说明:

// 寄生组合继承示例
function Shape(x, y) {
  this.x = x;
  this.y = y;
}

Shape.prototype.move = function(x, y) {
  this.x += x;
  this.y += y;
  console.log('Shape moved.');
}

function Circle(x, y, r) {
  Shape.call(this, x, y);
  this.r = r;
}

Circle.prototype = Object.create(Shape.prototype);
Circle.prototype.constructor = Circle;

Circle.prototype.getArea = function() {
  return Math.PI * this.r * this.r;
}

var circle = new Circle(10, 10, 5);
console.log(circle.getArea());
circle.move(5, 5);

// ES6 class继承示例
class Shape {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  move(x, y) {
    this.x += x;
    this.y += y;
    console.log('Shape moved.');
  }
}

class Circle extends Shape {
  constructor(x, y, r) {
    super(x, y);
    this.r = r;
  }

  getArea() {
    return Math.PI * this.r * this.r;
  }
}

var circle = new Circle(10, 10, 5);
console.log(circle.getArea());
circle.move(5, 5);

以上代码分别演示了寄生组合继承和ES6 class继承的实现和使用。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript实现继承的6种常用方式总结 - Python技术站

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

相关文章

  • Java 10的10个新特性总结

    Java 10的10个新特性总结 Java 10是Java技术的一个重要更新版本,它增加了许多新特性和改进,以下是Java 10的10个新特性: 局部变量的类型推导 Java 10中引入了var关键字,可以在局部变量声明时自动推导出其类型,使得代码更加简洁、可读性更高。例如: var number = 10; var str = "hello wo…

    other 2023年6月26日
    00
  • Ajax获取回调函数无法赋值给全局变量的问题

    Ajax获取回调函数无法赋值给全局变量的问题攻略 问题描述 在使用Ajax进行异步请求时,有时候我们希望将获取到的数据赋值给全局变量,以便在其他地方使用。然而,由于Ajax是异步执行的,回调函数在数据返回之前就已经执行完毕,导致无法直接将数据赋值给全局变量。这就是所谓的“Ajax获取回调函数无法赋值给全局变量的问题”。 解决方案 为了解决这个问题,我们可以采…

    other 2023年7月29日
    00
  • Java中获得当前静态类的类名

    Java中获得当前静态类的类名的完整攻略 在Java中,可以使用反射机制获取当前静态类的类名。本文将为您提供一份完整攻略,包括两个示例说明。 反射机制 反射机制是Java中的一种机制,可以在运行时获取类的信息,并动态地创建对象、调用方法等。反射机制可以实现动态加载类、动态调用方法等功能。 获取当前静态类的类名 在Java中,可以使用反射机制获取当前静态类的类…

    other 2023年5月5日
    00
  • 开发套件Altova MissionKit Enterprise 2019中文企业激活+安装教程(附下载)

    开发套件Altova MissionKit Enterprise 2019中文企业激活+安装教程(附下载)攻略 1. 下载Altova MissionKit Enterprise 2019 首先,你需要下载Altova MissionKit Enterprise 2019的安装文件。你可以在官方网站上找到该软件的下载链接。点击下载链接,选择适合你操作系统的版…

    other 2023年7月27日
    00
  • 批量列出所有文件名的批处理

    首先,我们需要明确批处理文件的编写目标,即在指定的文件夹中列出所有文件名,并将其输出到一个文本文件中。下面是完成这个目标的具体步骤: 步骤一:打开命令提示符窗口 在电脑屏幕上按下Win+R组合键,打开运行窗口,输入cmd并点击确定,即可打开命令提示符窗口。 步骤二:进入要扫描的文件夹 在命令提示符窗口中输入cd路径,其中路径是指要扫描的文件夹路径。例如,如果…

    other 2023年6月26日
    00
  • 三星note10开发者选项在哪?三星手机开发者选项启用教程

    三星Note10开发者选项在哪? 要激活三星Note10的开发者选项,请按照以下步骤逐个操作: 打开设置应用,在最底部找到“关于手机”选项。 在关于手机页面中,找到“软件信息”并点击。 在软件信息页面中,找到“构建号码”并点击七次。在第七次点击时,您将会看到一个弹出窗口告诉您已经开启了开发者选项。 回到设置页面,您现在将看到“开发者选项”在屏幕中。请点击进入…

    other 2023年6月26日
    00
  • Dota2控制台怎么打开 Dota2控制台命令大全分享

    Dota 2 控制台怎么打开 Dota 2 控制台是一个强大的工具,可以让玩家在游戏中使用各种命令和设置来改变游戏的行为。下面是打开 Dota 2 控制台的步骤: 打开 Dota 2 游戏客户端。 在主菜单界面,点击左上角的 \”设置\” 按钮。 在设置菜单中,选择 \”选项\” 选项卡。 在选项菜单中,找到 \”高级选项\” 部分。 在 \”高级选项\” …

    other 2023年8月6日
    00
  • 微信开发者工具怎么开启多账号调试?微信开发者工具开启多账号调试教程

    下面是详细的攻略。 1. 准备工作 在使用微信开发者工具前,需要确保电脑上已经安装了微信开发者工具,并且拥有微信公众号或小程序的开发者账号。 2. 开启多账号调试 点击微信开发者工具顶部菜单栏的“设置”按钮。 在弹出的设置窗口中,点击“开发者工具设置”。 在“其他”选项卡中,勾选“允许多开调试”选项。 在“项目”选项卡中,打开你要调试的小程序或公众号项目,然…

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