js继承的6种方式详解

以下是js继承的六种方式的详细攻略。

1. 原型链继承

原型链继承是JavaScript中最基本的继承方式之一,它通过将父类的实例对象作为子类的原型对象来实现继承。这种方式的缺点是,所有子类实例对象共享同一个原型对象,当父类原型对象中的引用类型属性被修改时,所有子类实例对象中对应属性的值都会同时改变,这个缺点也被称之为“原型污染”问题。

示例代码如下:

function Person(name) {
  this.name = name;
  this.friends = ["Ben", "Tom"];
}

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

function Student() {}

Student.prototype = new Person("Jack");
Student.prototype.constructor = Student;

var s1 = new Student();
s1.friends.push("Mike");
console.log(s1.friends); // 输出 ["Ben", "Tom", "Mike"]

var s2 = new Student();
console.log(s2.friends); // 输出 ["Ben", "Tom", "Mike"]

2. 构造函数继承

构造函数继承是通过借用父类构造函数来实现继承。这种方式解决了原型链继承中“原型污染”的问题,但带来的另外一个问题是,每个子类实例对象都会拥有一份自己的父类属性副本,而且无法继承父类原型对象上的属性和方法。

示例代码如下:

function Person(name) {
  this.name = name;
  this.friends = ["Ben", "Tom"];
}

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

function Student(name, grade) {
  Person.call(this, name);
  this.grade = grade;
}

var s1 = new Student("Jack", 1);
s1.friends.push("Mike");
console.log(s1.friends); // 输出 ["Ben", "Tom", "Mike"]

var s2 = new Student("Tom", 2);
console.log(s2.friends); // 输出 ["Ben", "Tom"]

3. 组合继承

组合继承是原型链继承和构造函数继承的组合使用,它通过借用父类构造函数来继承父类实例属性,通过将父类构造函数的实例对象作为子类原型对象来继承父类原型属性,从而既解决了“原型污染”问题,又避免了每个子类实例对象都拥有一份自己的父类属性副本的问题。

示例代码如下:

function Person(name) {
  this.name = name;
  this.friends = ["Ben", "Tom"];
}

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

function Student(name, grade) {
  Person.call(this, name);
  this.grade = grade;
}

Student.prototype = new Person();
Student.prototype.constructor = Student;

var s1 = new Student("Jack", 1);
s1.friends.push("Mike");
console.log(s1.friends); // 输出 ["Ben", "Tom", "Mike"]

var s2 = new Student("Tom", 2);
console.log(s2.friends); // 输出 ["Ben", "Tom"]

4. 原型式继承

原型式继承是借助原型链继承的方式来实现对象之间的继承关系。它通过创建一个临时性的构造函数,将传入的对象作为这个构造函数的原型对象来创建新的对象,从而实现继承。

示例代码如下:

var person = {
  name: "Jack",
  friends: ["Ben", "Tom"]
};

var student = Object.create(person);
student.grade = 1;

var student2 = Object.create(person);
student2.grade = 2;

student.friends.push("Mike");
console.log(student.friends); // 输出 ["Ben", "Tom", "Mike"]

console.log(student2.friends); // 输出 ["Ben", "Tom", "Mike"]

5. 寄生式继承

寄生式继承是基于原型式继承的一种增强版,它利用一个虚构的构造函数,在原型式继承的基础上添加了一些新的属性和方法,并返回这个虚构的构造函数。

示例代码如下:

function createStudent(person, grade) {
  var student = Object.create(person);
  student.grade = grade;

  student.sayGrade = function() {
    console.log(this.grade);
  };

  return student;
}

var person = {
  name: "Jack",
  friends: ["Ben", "Tom"]
};

var student = createStudent(person, 1);
student.friends.push("Mike");
console.log(student.friends); // 输出 ["Ben", "Tom", "Mike"]

6. 寄生组合式继承

寄生组合式继承是通过组合继承和寄生式继承的方式来实现继承。这种方式解决了组合继承中重复执行父类构造函数的问题,并且避免了父类构造函数中实例属性被重复定义的问题。

示例代码如下:

function Person(name) {
  this.name = name;
  this.friends = ["Ben", "Tom"];
}

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

function Student(name, grade) {
  Person.call(this, name);
  this.grade = grade;
}

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

inheritPrototype(Student, Person);

var s1 = new Student("Jack", 1);
s1.friends.push("Mike");
console.log(s1.friends); // 输出 ["Ben", "Tom", "Mike"]

var s2 = new Student("Tom", 2);
console.log(s2.friends); // 输出 ["Ben", "Tom"]

希望以上内容能够帮助您更好地理解JavaScript中的继承方式。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:js继承的6种方式详解 - Python技术站

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

相关文章

  • 如何解决ASP.NET新增时多字段取值的问题

    问题描述: 在ASP.NET中添加新纪录时,需要从前端获取多个字段的数值,但是在处理时遇到了问题,无法从前端同时获取多个字段的数值,需要解决这个问题。 解决方案: 1.前端传递JSON数据 前端通过JSON格式的数据将需要添加的多个字段的数值传递给后端,后端进行反序列化并取出对应字段的值进行处理。 示例代码: 前端代码: var data = { field…

    other 2023年6月25日
    00
  • Go mod包管理工具详解

    Go mod包管理工具详解 Go mod是Go语言自带的包管理工具,用于管理项目的依赖关系。以下是关于Go mod的详细攻略。 1. 初始化Go mod 要使用Go mod管理项目的依赖关系,首先需要在项目根目录下初始化Go mod。 go mod init <module-name> 在上述命令中,<module-name>是你的项…

    other 2023年10月12日
    00
  • html页面的局部刷新

    HTML页面的局部刷新 随着Web技术的不断进步,现在很少有网站会再采用传统的刷新整个页面的方式来更新数据了。而使用局部刷新的方式,可以更为高效、流畅地提供数据更新与用户交互。本文将介绍HTML页面的局部刷新以及实现方法。 局部刷新的基本原理 相信大家对于AJAX(Asynchronous JavaScript and XML,异步 JavaScript 和…

    其他 2023年3月28日
    00
  • XenoDream Jux如何安装激活?XenoDream Jux分形软件激活教程

    以下是详细的 XenoDream Jux 安装激活教程。 下载安装XenoDream Jux 首先到官网下载 XenoDream Jux 安装包,链接:https://www.xenodream.com/jux.html。 下载完成后,打开 XenoDream Jux 的安装程序。 根据提示进行安装。安装过程中需要选择对应的安装路径,建议保留默认设置。 安装…

    other 2023年6月27日
    00
  • [持续更新]安卓6.0/Android M开发者预览版3更新内容大全

    持续更新安卓6.0/ Android M开发者预览版3更新内容大全 简介 本文章主要介绍安卓6.0/ Android M开发者预览版3更新的详细内容。该预览版的更新主要是对先前版本的一些已知问题的修复和一些新增功能的添加。本文将会列举这些修改和新增功能,并对其中重要的信息进行一些补充和解析。 更新内容 1. 权限控制 Android M相对于以前的版本,在权…

    other 2023年6月26日
    00
  • jQuery中$原理实例分析

    jQuery中$原理实例分析 什么是$符号 $符号是jQuery的简写。在jQuery中,所有的代码都是由$符号开头的。$符号的作用是为了简化JavaScript程序。同时,也可以帮助我们快速、安全地操作HTML文档。 $符号的实现原理 $符号是通过调用jQuery函数实现的。简单来说,jQuery函数会返回一个对象。这个对象上封装了许多函数和属性,我们可以…

    other 2023年6月27日
    00
  • 深入了解Java虚拟机栈以及内存模型

    深入了解Java虚拟机栈以及内存模型攻略 1. Java虚拟机栈 Java虚拟机栈是Java程序运行时的一块内存区域,用于存储方法的局部变量、方法参数、返回值和操作数栈等信息。以下是Java虚拟机栈的一些重要特点: 栈帧:每个方法在运行时都会创建一个栈帧,栈帧包含了方法的局部变量表、操作数栈、动态链接、方法返回地址等信息。 线程私有:每个线程都有自己的Jav…

    other 2023年8月2日
    00
  • Office 如何打印A4不干胶标签纸

    下面是关于Office如何打印A4不干胶标签纸的完整攻略,包括设置、调整和两个示例说明。 设置 在打印A4不干胶标签纸之前,需要进行以下设置: 打开Word文档,选择“页面布局”选项卡。 在“页面设置”中,选择“纸张大小”为A4。 在“页边距”中,选择“上下左右”均为0.5厘米。 在“多页”中,选择“1页/纸张”。 点击“确定”按钮保存设置。 调整 在设置完…

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