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日

相关文章

  • 一文学会Flex布局 – Nicander – 博客园

    一文学会Flex布局 – Nicander – 博客园 什么是Flex布局 Flex布局是指弹性盒模型,是一种用于页面布局的模型。Flex布局可以使用在普通的块级元素上,或者被应用到一个容器元素上。 在容器元素上应用Flex布局,容器的子元素将会改变它们在容器中的排列方式,包括它们的方向,对齐方式以及它们的大小。这种方式可以给我们带来更好的灵活性和响应式设计…

    其他 2023年3月28日
    00
  • 将文件夹内的文件名称导入到文本文档(记事本)中的方法图文介绍

    以下是将文件夹内的文件名称导入到文本文档(记事本)中的方法图文介绍: 步骤一:打开命令提示符 在 Windows 中,按下“Win + R”组合键,输入“cmd”,按下“Enter”键,即可打开命令提示符。 步骤二:进入需要导出文件名的文件夹 在命令提示符中,通过“cd”命令进入需要导出文件名的文件夹。例如,需要导出文件夹“D:\test”内的文件名,可以在…

    other 2023年6月26日
    00
  • Win10应用程序无法正常启动提示错误0xc000007b解决方法

    问题描述: 在使用Win10系统时,有时会出现应用程序无法正常启动的情况,提示错误代码为0xc000007b。这可能会让用户感到非常苦恼,因为发生这种情况时,无法使用相关的应用程序。 问题的原因: 通常,应用程序无法正常启动的原因是由于系统丢失或损坏了一些必要的系统文件,或是电脑缺少一些必要的运行库文件。另外,有些应用程序可能是32位程序,而运行在64位系统…

    other 2023年6月25日
    00
  • C++使用递归函数和栈操作逆序一个栈的算法示例

    下面是使用递归函数和栈操作逆序一个栈的算法示例完整攻略。 原理与思路 首先,我们需要了解递归函数和栈的概念。 递归函数是一种函数调用自身的方法,它可以将复杂的问题分解成多个相同或类似的小问题来解决。在递归函数中,每一层的函数调用都会开辟新的栈帧,形成一个栈式结构。 栈是一种先进后出(Last In First Out,LIFO)的数据结构。在栈中,最后一个入…

    other 2023年6月27日
    00
  • vuestyle字体加粗

    当您在Vue项目中使用vuestyle时,可以使用CSS样式来设置字体加粗。以下是详细的步骤和两个示例: 1 使用CSS样式设置字体加粗 在Vue项目中,您可以使用CSS样式设置体加粗。您可以在组件的style标签中添加CSS样式,或者在全局样式表中添加CSS样式。 以下是CSS样设置字体加粗的步骤: 1.1 在组件的style标签中添加CSS样式 在组件的…

    other 2023年5月6日
    00
  • pytest用例间参数传递的两种实现方式示例

    Pytest用例间参数传递的两种实现方式示例 在Pytest中,有两种常见的方式可以在测试用例之间传递参数。下面将详细介绍这两种方式,并提供示例说明。 1. 使用pytest.fixture装饰器 pytest.fixture装饰器可以用于创建可重用的测试用例参数。通过将参数定义为fixture,可以在多个测试用例中共享这些参数。 示例说明: import …

    other 2023年7月29日
    00
  • PHP面相对象中的重载与重写

    PHP面向对象中的重载与重写 在PHP面向对象编程中,重载(overloading)和重写(overriding)是两个常用的概念。它们可以帮助开发者更加灵活地处理对象的属性和方法。接下来将进行详细解释。 重载 重载是指在类中定义特定方法来处理特定的操作符或者方法。这些方法可以被调用来为对象设置属性或者执行方法的访问。 __get()和__set()方法 _…

    other 2023年6月26日
    00
  • C++统计中英文大小写字母、数字、空格及其他字符个数的方法

    C++统计中英文大小写字母、数字、空格及其他字符个数的方法 以下是一种用C++编写的统计中英文大小写字母、数字、空格及其他字符个数的方法的完整攻略。 步骤1:包含必要的头文件 首先,我们需要包含 <iostream> 和 <cctype> 头文件,以便使用C++的输入输出功能和字符处理函数。 #include <iostream…

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