js继承的6种方式详解

yizhihongxing

以下是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日

相关文章

  • Android开发实现仿QQ消息SwipeMenuListView滑动删除置顶功能【附源码下载】

    很高兴为您提供关于\”Android开发实现仿QQ消息SwipeMenuListView滑动删除置顶功能【附源码下载】\”的完整攻略。以下是详细步骤: 步骤1:导入SwipeMenuListView库 首先,您需要导入SwipeMenuListView库到您的Android项目中。您可以通过在项目的build.gradle文件中添加以下依赖项来完成此操作: …

    other 2023年9月6日
    00
  • 【转载】2012年七个免费asp空间分享-支持asp、asp.net的空间

    【转载】2012年七个免费asp空间分享-支持asp、asp.net的空间 最近,我们网站收到不少用户咨询关于免费asp空间的问题,因此在这里给大家分享一些比较不错的免费asp空间。这些空间均支持asp、asp.net语言,供大家参考。 1. 000webhost 000webhost是一家提供免费网站空间的网站。该网站提供了“完全免费”的空间,无需付费,也…

    其他 2023年3月28日
    00
  • 使用C语言实现字符串逆序操作案例

    使用C语言实现字符串逆序操作可以分为以下步骤: 第一步:定义字符串及其长度 在C语言中,字符串是以数组的形式存储的,需要我们定义一个字符数组并初始化。此外,我们还需要获取字符串的长度,用于后续操作。 以下是示例代码: #include <stdio.h> #include <string.h> int main() { char st…

    other 2023年6月27日
    00
  • Mac分区失败 未能修改分区图,因为文件系统验证失败该怎么解决?

    解决Mac分区失败的问题,首先需要了解该错误的原因。一般来说,Mac分区失败 未能修改分区图,因为文件系统验证失败的错误是由于文件系统出现了问题导致的。文件系统是一个非常重要的组成部分,它负责储存文件、访问权限和其他系统信息。一旦文件系统出现问题,就会导致分区失败错误。 下面是解决Mac分区失败的完整攻略: 步骤1:备份数据在进行任何分区操作之前,一定要备份…

    other 2023年6月27日
    00
  • Android系统添加自定义鼠标样式通过按键切换实例详解

    添加自定义鼠标样式可以让Android系统在使用鼠标时更加个性化,通过按键切换实现则可以方便地更改鼠标样式。以下是实现方法的详细说明: 步骤1:准备自定义鼠标样式文件 首先需要准备自定义鼠标样式文件,可以选择一些已有的鼠标样式图片或者自行设计制作。一般情况下,图片格式需要是PNG格式,大小为32×32像素。 步骤2:将自定义鼠标样式文件放到指定目录下 将所有…

    other 2023年6月25日
    00
  • C语言基础知识点指针的使用

    那么让我们来详细讲解一下“C语言基础知识点指针的使用”的完整攻略。 一、指针的定义和使用 指针是变量的一种,不同之处在于指针存储的是一个地址,这个地址指向的是另一个变量的位置,而不是存储的实际值。通过指针,我们可以直接操作指向的变量而不需要知道变量的名字。 指针定义的语法格式如下: <数据类型>* <指针变量名>; 其中,数据类型表示…

    other 2023年6月27日
    00
  • proto3协议指引

    proto3协议指引 什么是proto3协议? proto3是Google开源的一种用于序列化结构化数据的协议,它的全称是Protocol Buffers 3。它是proto2版本的升级版,拥有更简洁、更强大的特性。 proto3协议支持多种编程语言,包括Java、Python、Go、C++等。它支持先定义数据结构,再将数据结构编译成目标语言的数据访问类,从…

    其他 2023年3月28日
    00
  • yii2框架整体结构

    Yii2 是一个高性能的 PHP 框架,它采用了 MVC 设计模式,提供了丰富的功能和组件,使得开发者可以快速构建高质量的 Web 应用程序。在本攻略,我们将详细讲 Yii2 框架的整体结构,并提供两个示例说明。 Yii2 框架整体结构 Yii2架的整体结构如: app/ 应用程序目录 assets/ 应用程序资源文件 commands/ 命令行脚本 com…

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