前端JavaScript篇之对象继承的方式有哪些?

目录

  • 对象继承的方式有哪些?
    • 1. 原型链继承
    • 2. 借用构造函数
    • 3. 组合继承
    • 4. 原型式继承
    • 5. 寄生式组合继承


对象继承的方式有哪些?

1. 原型链继承

当使用原型链继承时,子类型的原型对象被设置为父类型的一个实例。这意味着子类型通过其原型可以访问父类型的属性和方法。

// 父类型
function Animal(name) {this.name = name
}Animal.prototype.getName = function () {return this.name
}// 子类型
function Dog(age) {this.age = age
}// 将子类型的原型设置为父类型的实例
Dog.prototype = new Animal('Tommy')var dog1 = new Dog(3)
var dog2 = new Dog(5)console.log(dog1.getName()) // 输出 "Tommy"
console.log(dog2.getName()) // 输出 "Tommy"

请添加图片描述

思路:

  1. 首先定义了一个父类型 Animal,它有一个属性 name 和一个方法 getName。
  2. 接着定义了一个子类型 Dog,它有一个属性 age。
  3. 将 Dog 的原型设置为 new Animal("Tommy"),这样 Dog 就继承了 Animal 的属性和方法。
  4. 创建两个 Dog 的实例 dog1 和 dog2,它们都能够访问 Animal 的 getName 方法。

虽然原型链继承简单易懂,但是存在共享引用类型属性的问题。如果在子类型中修改了引用类型的属性,会影响到所有子类型的实例。

  • 注意:在包含引用类型的属性时,会有共享数据的问题。

2. 借用构造函数

当使用借用构造函数来实现继承时,子类型的构造函数内部调用父类型的构造函数,通过这种方式可以在子类型中向父类型传递参数。

// 父类型
function Person(name) {this.name = name
}// 子类型
function Employee(name, position) {Person.call(this, name) // 在子类型的构造函数内部调用父类型的构造函数,传入name参数this.position = position
}var emp1 = new Employee('Alice', 'Manager')
var emp2 = new Employee('Bob', 'Developer')console.log(emp1.name) // 输出 "Alice"
console.log(emp1.position) // 输出 "Manager"
console.log(emp2.name) // 输出 "Bob"
console.log(emp2.position) // 输出 "Developer"

请添加图片描述

思路:

  1. 首先定义了一个父类型 Person,它有一个属性 name。
  2. 接着定义了一个子类型 Employee,它有一个属性 position。
  3. 在 Employee 的构造函数内部使用 Person.call(this, name),这样就能够在 Employee 中向 Person 传递参数 name。
  4. 创建两个 Employee 的实例 emp1 和 emp2,它们分别拥有各自的 name 和 position 属性。

借用构造函数方式解决了不能向超类型传递参数的问题,但无法实现函数方法的复用,并且超类型原型定义的方法子类型也没有办法访问到。

  • 注意:无法复用函数方法,只能继承构造函数的属性。

3. 组合继承

组合继承是将原型链继承和借用构造函数继承相结合的一种继承方式,通过这种方式可以解决原型链继承和借用构造函数继承各自的缺点。

// 父类型
function Animal(name) {this.name = name
}Animal.prototype.getName = function () {return this.name
}// 子类型
function Dog(name, age) {Animal.call(this, name) // 借用构造函数继承属性this.age = age
}// 将子类型的原型设置为父类型的实例
Dog.prototype = new Animal()var dog1 = new Dog('Buddy', 3)
var dog2 = new Dog('Max', 5)console.log(dog1.getName()) // 输出 "Buddy"
console.log(dog2.getName()) // 输出 "Max"

请添加图片描述

思路:

  1. 首先定义了一个父类型 Animal,它有一个属性 name 和一个方法 getName。
  2. 接着定义了一个子类型 Dog,它有一个属性 age。
  3. 在 Dog 的构造函数内部使用 Animal.call(this, name),这样就能够在 Dog 中向 Animal 传递参数 name,并且避免了引用类型属性共享的问题。
  4. 将 Dog 的原型设置为 new Animal(),这样 Dog 就继承了 Animal 的方法。
  5. 创建两个 Dog 的实例 dog1 和 dog2,它们分别拥有各自的 name 和 age 属性,并且能够访问 Animal 的 getName 方法。

组合继承通过借用构造函数来继承属性,通过将子类型的原型设置为父类型的实例来继承方法,解决了原型链继承和借用构造函数继承各自的问题,是一种较为常用的继承方式。

  • 注意:调用了两次父类构造函数,导致子类原型中多了不必要的属性。

4. 原型式继承

原型式继承是一种基于已有对象创建新对象的继承方式,适用于简单对象的继承。在 JavaScript 中可以使用 Object.create 方法来实现原型式继承。

// 原型对象
var person = {name: 'John',age: 30,greet: function () {return 'Hello, my name is ' + this.name + ' and I am ' + this.age + ' years old.'}
}// 基于原型对象创建新对象
var anotherPerson = Object.create(person)anotherPerson.name = 'Alice' // 修改属性值
anotherPerson.age = 25 // 修改属性值console.log(anotherPerson.greet()) // 输出 "Hello, my name is Alice and I am 25 years old."

请添加图片描述

思路:

  1. 首先定义了一个原型对象 person,它有属性 name 和 age,以及一个方法 greet。
  2. 使用 Object.create 方法基于 person 创建了一个新对象 anotherPerson。
  3. 修改了 anotherPerson 的 name 和 age 属性值。
  4. 调用 anotherPerson 的 greet 方法,输出了修改后的信息。

原型式继承通过复制给定的对象来创建新对象,新对象可以共享原型对象的属性和方法。这种继承方式适合在不需要单独构造函数的情况下进行对象的继承。但需要注意的是,由于共享特性,对新对象的修改会影响到原型对象以及其他基于同一原型对象创建的对象。

  • 注意:无法实现函数的复用。

5. 寄生式组合继承

寄生式组合继承是结合了寄生式继承和组合继承的优点,避免了调用两次父类构造函数以及在子类原型中创建不必要的属性

// 寄生式继承
function inheritPrototype(subType, superType) {var prototype = Object.create(superType.prototype) // 创建对象prototype.constructor = subType // 增强对象subType.prototype = prototype // 赋值对象
}// 父类型
function Animal(name) {this.name = name
}Animal.prototype.sayName = function () {console.log(this.name)
}// 子类型
function Dog(name, age) {Animal.call(this, name) // 继承属性this.age = age
}// 使用寄生式继承来继承父类型的原型
inheritPrototype(Dog, Animal)var dog1 = new Dog('Buddy', 3)
var dog2 = new Dog('Max', 5)dog1.sayName() // 输出 "Buddy"
dog2.sayName() // 输出 "Max"

请添加图片描述

思路:

  1. 首先定义了一个父类型 Animal,它有一个属性 name 和一个方法 sayName。
  2. 接着定义了一个子类型 Dog,它有一个属性 age。
  3. 在 Dog 的构造函数内部使用 Animal.call(this, name),这样就能够在 Dog 中向 Animal 传递参数 name。
  4. 使用 inheritPrototype 函数,通过寄生式继承来继承父类型的原型,避免了调用两次父类构造函数以及在子类原型中创建不必要的属性。
  5. 创建两个 Dog 的实例 dog1 和 dog2,它们分别拥有各自的 name 和 age 属性,并且能够访问 Animal 的 sayName 方法。

寄生式组合继承是一种常用的继承方式,克服了组合继承的缺点,既能够继承父类的属性,又能够保持原型链完整,使得子类实例既能够访问自己的属性和方法,也能够访问父类的属性和方法。

以上是对象继承的几种方式及其特点,选择合适的方式取决于具体需求,寄生式组合继承是其中最常用的一种方式。

持续学习总结记录中,回顾一下上面的内容:
对象继承的方式包括原型链继承、借用构造函数继承、组合继承、原型式继承、寄生式继承和寄生式组合继承。原型链继承通过将子类型的原型设置为父类型的实例来实现继承;借用构造函数继承通过在子类型的构造函数内部调用父类型的构造函数来实现继承;组合继承结合了原型链继承和借用构造函数继承的优点;原型式继承是基于已有对象创建新对象的继承方式;寄生式继承是在原型式继承的基础上增强对象,返回新对象;寄生式组合继承结合了寄生式继承和组合继承的优点,避免了调用两次父类构造函数以及在子类原型中创建不必要的属性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.tpcf.cn/news/677854.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

线性表的插入

#define MaxSize 10 //定义最大长度 typeof struct{ int data[MaxSize]; //用静态“数组”存放数据元素 int length; //顺序表的当前长度 }SeqList; //顺序表的类型定义 bool ListInsert(SeqList &L,int i,int e){ if(i<1 || i>L.length1)…

VUE学习——数组变化侦测

官方文档 变更方法&#xff1a; 使用之后&#xff0c;ui可以直接发生改变。改变原数组 替换数组&#xff1a; 使用之后需要接受重新赋值&#xff0c;不然ui不发生改变。不改变原数组

第70讲axios后端请求工具类封装

axios工具类封装&#xff1a; // 引入axios import axios from axios;// 创建axios实例 const httpService axios.create({// url前缀-http:xxx.xxx// baseURL: process.env.BASE_API, // 需自定义baseURL:http://localhost:80/,// 请求超时时间timeout: 3000 // 需自定义 })…

嵌入式系统:挑战与机遇并存的领域

嵌入式系统&#xff1a;挑战与机遇并存的领域嵌入式系统是一个既具有挑战性又充满前景的领域。要成为一名合格的嵌入式系统工程师&#xff0c;需要经过大量的学习和实践。然而&#xff0c;进入这个领域时&#xff0c;刚入行可能会面临许多困境。让我们一起探讨一下嵌入式系统工…

matplotlib的学习

matplotlib绘图两种方式: #面向对象方法 import numpy as np import matplotlib.pyplot as plt x = np.linspace(0, 5, 100) fig, ax = plt.subplots(figsize=(10, 5)) ax.plot(x, x) ax.plot(x, x ** 2) ax.set_xlabel(‘x’) ax.set_ylabel(‘y’) plt.show() #直接使用pyplo…

Python爬虫实战 | 京东平台电商API接口采集京东商品京东工业商品详情数据

item_get-获得JD商品详情API测试 公共参数 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09;secretString是调用密钥api_nameString是API接口名称&#xff08;包括在请求地址中&#xff09;[item_search,item_get,item_search_shop等]cac…

【Maven】依赖、构建管理 继承与聚合 快速学习(3.6.3 )

文章目录 Maven是什么&#xff1f;一、Maven安装和配置本地配置文件设置idea配置本地maven 二、基于IDEA的Maven工程创建2.1 Maven工程GAVP属性2.2 Idea构建Maven JavaEE工程 三、Maven工程项目结构说明四、Maven核心功能依赖和构建管理4.1 依赖管理和配置4.2 依赖传递和冲突4.…

【数学建模】【2024年】【第40届】【MCM/ICM】【E题 财产保险的可持续性】【解题思路】

一、题目 &#xff08;一&#xff09; 赛题原文 2024 ICM Problem E: Sustainability of Property Insurance Extreme-weather events are becoming a crisis for property owners and insurers. The world has endured “more than $1 trillion in damages from more than …

华为机试真题实战应用【赛题代码篇】-自守数(附Java、C++和python代码)

目录 问题描述 思路解析 思路1 思路2 代码实现 Java 代码2

vue+springboot前后端视频文件等的上传与展示(基于七牛云)

前言&#xff1a;在初步说明完成功能之前&#xff0c;我会把重要的部分说明下。后续我会细化。 vue视频文件上传 其实这里和图片这些文件就是一样的。因为上传只是把我们想在云端展示的文件按等传输到云端的bucket。然后方便网站去请求引用。 有人问我我就说明下。这种东西无…

ClickHouse--02--安装

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 安装官网 &#xff1b;[https://clickhouse.com/docs/zh/getting-started/install](https://clickhouse.com/docs/zh/getting-started/install)![在这里插入图片描述…

c语言游戏实战(7):扫雷

前言&#xff1a; 扫雷是一款经典的单人益智游戏&#xff0c;它的目标是在一个方格矩阵中找出所有的地雷&#xff0c;而不触碰到任何一颗地雷。在计算机编程领域&#xff0c;扫雷也是一个非常受欢迎的项目&#xff0c;因为它涉及到许多重要的编程概念&#xff0c;如数组、循环…

Python中的嵌套字典访问与操作详解

前言 在Python编程中&#xff0c;嵌套字典是一种常见的数据结构&#xff0c;它可以以层次结构的方式组织和存储数据。嵌套字典通常包含字典内嵌套在其他字典中&#xff0c;创建了一种多层级的数据结构。本文将详细介绍如何在Python中访问和操作嵌套字典&#xff0c;包括访问、…

js中bind、call、apply 区别(如何实现)

文章目录 一、作用二、区别applycallbind小结 三、实现 一、作用 call、apply、bind作用是改变函数执行时的上下文&#xff0c;简而言之就是改变函数运行时的this指向 那么什么情况下需要改变this的指向呢&#xff1f;下面举个例子 var name "lucy"; var obj {n…

Android:Ionic框架使用实例

Ionic学习 ionic 是一个强大的 HTML5 应用程序开发框架(HTML5 Hybrid Mobile App Framework )。通过使用H5,JS,CSS构建接近原生体验的移动应用程序。 ionic放弃对IOS6和Android4.1以下的版本的支持,提高应用程序的运行效率。 Ionic官网地址: Ionic Framework - The Cross-Pla…

类的6个默认成员函数

如果一个类中什么成员都没有,简称为空类空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生成以下6个默认成默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数 C类的6个默认成员函数包括默认构造函数、析构函数、拷贝构造函数、拷贝赋值…

【leetcode热题100】 格雷编码

n 位格雷码序列 是一个由 2n 个整数组成的序列&#xff0c;其中&#xff1a; 每个整数都在范围 [0, 2n - 1] 内&#xff08;含 0 和 2n - 1&#xff09;第一个整数是 0一个整数在序列中出现 不超过一次每对 相邻 整数的二进制表示 恰好一位不同 &#xff0c;且第一个 和 最后一…

Linux基础-配置网络

Linux配置网络的方式 1.图形界面 右上角-wired-配置 点加号-新建网络配置文件2.NetworkManager工具 2.1用图形终端nmtui 1.新建网络配置文件add 1.指定网络设备的类型Ethernet 2.配置网络配置文件的名称&#xff0c;名称可以有空格 3.配置网络配置文件对应的物理网络设备的…

【5G NR】【一文读懂系列】移动通讯中使用的信道编解码技术-Viterbi译码原理

目录 一、引言 二、Viterbi译码的基本原理 2.1 卷积码与网格图 2.2 Viterbi算法的核心思想 2.3 路径度量与状态转移 三、Viterbi译码算法工作原理详解 3.1 算法流程 3.2 关键步骤 3.3 译码算法举例 3.4 性能特点 四、Viterbi译码的应用场景 4.1 移动通信系统 4.2 卫…

2024.2.10 DMS(数据库管理系统)初体验

数据库管理系统(Database Management System)是一种操纵和管理数据库的大型软件&#xff0c;用于建立、使用和维护数据库&#xff0c;简称DBMS。它对数据库进行统一的管理和控制&#xff0c;以保证数据库的安全性和完整性。用户通过DBMS访问数据库中的数据&#xff0c;数据库管…