【前端知识】Javascript进阶-类和继承

news2024/12/17 9:57:08

文章目录

    • 概述
      • 一、类(Class)
      • 二、继承(Inheritance)
    • 三、继承的实现方式
    • 作用
      • 一、类和作用
      • 二、继承和作用

概述

当然可以,以下是对JavaScript中类和继承的详细介绍:

一、类(Class)

  1. 定义

    • 类是创建对象的模板或蓝图,它定义了对象的属性和方法。
    • 在JavaScript中,类是通过class关键字定义的。
  2. 语法

    • 类的定义以class关键字开始,后面跟着类名。
    • 类体由一对大括号{}包围,其中包含构造函数和方法。
  3. 构造函数

    • 构造函数是一个特殊的方法,用于在创建对象时初始化对象的属性。
    • 构造函数在类中使用constructor关键字定义。
  4. 方法

    • 方法是类中的函数,用于执行特定的操作。
    • 方法定义在类体中,可以通过this关键字访问对象的属性和其他方法。
  5. 静态方法

    • 静态方法是属于类本身的方法,而不是属于类的实例。
    • 静态方法使用static关键字定义,可以通过类名直接调用。
  6. 示例

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

  speak() {
    console.log(`${this.name} makes a sound.`);
  }

  static species() {
    return 'Animal';
  }
}

const dog = new Animal('Doggy');
dog.speak(); // 输出: Doggy makes a sound.
console.log(Animal.species()); // 输出: Animal

二、继承(Inheritance)

  1. 定义

    • 继承是面向对象编程中的一个重要概念,它允许一个类(子类)继承另一个类(父类)的属性和方法。
    • 通过继承,子类可以重用父类的代码,从而实现代码的复用和扩展。
  2. 语法

    • 在JavaScript中,子类使用extends关键字来继承父类。
    • 子类可以重写父类的方法,也可以添加新的属性和方法。
  3. super关键字

    • super关键字用于在子类中调用父类的构造函数和方法。
    • 在子类的构造函数中,super()必须被调用,以确保父类的属性被正确初始化。
  4. 示例

class Dog extends Animal {
  constructor(name, breed) {
    super(name); // 调用父类的构造函数
    this.breed = breed;
  }

  speak() {
    console.log(`${this.name} barks.`); // 重写父类的方法
  }

  static species() {
    return 'Dog'; // 重写父类的静态方法
  }
}

const myDog = new Dog('Buddy', 'Golden Retriever');
myDog.speak(); // 输出: Buddy barks.
console.log(Dog.species()); // 输出: Dog
  1. 继承的优缺点
    • 优点
      • 代码复用:通过继承,子类可以重用父类的属性和方法,避免重复编写代码。
      • 组织代码:通过继承,可以将相关的属性和方法封装在一个类中,使代码结构更清晰。
      • 多态:子类可以重写父类的方法,从而根据实际情况执行不同的代码逻辑。
    • 缺点
      • 复杂性增加:随着继承层次的增加,代码可能会变得更加复杂和难以维护。
      • 耦合度提高:子类与父类之间存在紧密的耦合关系,如果父类发生变化,子类也可能需要相应地进行修改。

三、继承的实现方式

在JavaScript中,实现继承的方式主要有以下几种,每种方式都有其独特的优点和缺点,并且适用于不同的场景。下面是每种继承方式的样例代码:

  1. 原型链继承
function Parent(name) {
    this.name = name;
    this.colors = ['red', 'blue', 'green'];
}

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

function Child(name, age) {
    // 继承Parent的属性和方法
    Parent.call(this, name); // 借用构造函数继承属性
    this.age = age;
}

// 设置Child的原型为Parent的一个实例,实现原型链继承方法
Child.prototype = new Parent();
Child.prototype.constructor = Child;

Child.prototype.sayAge = function() {
    console.log(this.age);
};

let child1 = new Child('Alice', 18);
let child2 = new Child('Bob', 20);

child1.colors.push('black');
console.log(child1.colors); // ['red', 'blue', 'green', 'black']
console.log(child2.colors); // ['red', 'blue', 'green', 'black'] // 共享了父类实例的属性
console.log(child1.sayName() === child2.sayName()); // true,方法也被共享

注意:上面的代码实际上混合了原型链继承和借用构造函数继承,这不是纯粹的原型链继承。纯粹的原型链继承应该只设置子类的原型为父类的一个实例,不调用父类的构造函数。但这样做会导致子类实例无法拥有父类构造函数中定义的属性。为了避免这个问题,通常会结合使用借用构造函数继承和原型链继承,即组合继承。下面的样例将展示组合继承。

  1. 借用构造函数继承(也称为伪类继承):
function Parent(name) {
    this.name = name;
    this.colors = ['red', 'blue', 'green'];
}

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

function Child(name, age) {
    // 借用Parent的构造函数来继承属性
    Parent.call(this, name);
    this.age = age;
}

// Child没有继承Parent的原型方法和属性
let child = new Child('Alice', 18);
console.log(child.name); // Alice
console.log(child.age); // 18
// console.log(child.sayName()); // TypeError: child.sayName is not a function
  1. 组合继承(原型链继承 + 借用构造函数继承):
function Parent(name) {
    this.name = name;
    this.colors = ['red', 'blue', 'green'];
}

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

function Child(name, age) {
    // 借用Parent的构造函数来继承属性
    Parent.call(this, name);
    this.age = age;
}

// 原型链继承Parent的方法
Child.prototype = new Parent(); // 注意:这里不会执行Parent构造函数中的代码,只设置原型
Child.prototype.constructor = Child;

Child.prototype.sayAge = function() {
    console.log(this.age);
};

let child1 = new Child('Alice', 18);
let child2 = new Child('Bob', 20);

child1.colors.push('black');
console.log(child1.colors); // ['red', 'blue', 'green', 'black']
console.log(child2.colors); // ['red', 'blue', 'green'] // 没有共享属性
console.log(child1.sayName() === child2.sayName()); // true,方法被共享
  1. 原型式继承(使用Object.create):
let person = {
    isHuman: false,
    printIntroduction: function() {
        console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
    }
};

let me = Object.create(person);

me.name = 'John'; // "name" 是 me 的一个属性
me.isHuman = true; // "isHuman" 是 me 的一个属性

me.printIntroduction(); // 输出: "My name is John. Am I human? true"
  1. 寄生组合式继承
function Parent(name) {
    this.name = name;
    this.colors = ['red', 'blue', 'green'];
}

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

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

// 创建一个父类实例的副本,并将其原型设置为父类的原型
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;

Child.prototype.sayAge = function() {
    console.log(this.age);
};

let child1 = new Child('Alice', 18);
let child2 = new Child('Bob', 20);

child1.colors.push('black');
console.log(child1.colors); // ['red', 'blue', 'green', 'black']
console.log(child2.colors); // ['red', 'blue', 'green'] // 没有共享属性
console.log(child1.sayName() === child2.sayName()); // true,方法被共享
  1. ES6类继承
class Parent {
    constructor(name) {
        this.name = name;
        this.colors = ['red', 'blue', 'green'];
    }

    sayName() {
        console.log(this.name);
    }
}

class Child extends Parent {
    constructor(name, age) {
        super(name); // 调用父类的构造函数
        this.age = age;
    }

    sayAge() {
        console.log(this.age);
    }
}

let child1 = new Child('Alice', 18);
let child2 = new Child('Bob', 20);

child1.colors.push('black');
console.log(child1.colors); // ['red', 'blue', 'green', 'black']
console.log(child2.colors); // ['red', 'blue', 'green'] // 没有共享属性
console.log(child1.sayName() === child2.sayName()); // true,方法被共享

请注意,上面的样例代码中有些包含了不必要的或错误的继承方式混合(如第一个样例中的原型链继承和借用构造函数继承的混合),仅用于说明各种继承方式的概念和区别。在实际开发中,应该根据需要选择最合适的继承方式。

作用

在JavaScript中,类和继承的作用主要体现在以下几个方面:

一、类和作用

  1. 代码组织

    • 类提供了一种将相关功能(属性和方法)封装在一起的方式,使得代码更加模块化和易于管理。
    • 通过类,开发者可以将复杂的逻辑分解成更小的、可复用的组件。
  2. 面向对象编程

    • 类是面向对象编程(OOP)的核心概念之一。
    • 在JavaScript中,通过类的使用,开发者可以实现封装、继承和多态等OOP特性。
  3. 代码复用

    • 类允许创建多个具有相同属性和方法的对象实例,从而实现了代码的重用。
    • 通过定义类,开发者可以避免在每个对象中重复编写相同的代码。
  4. 数据隐藏

    • 类提供了一种将内部状态(私有属性)与外部行为(公共方法)分离的方式。
    • 通过类的封装,开发者可以隐藏对象的内部实现细节,只暴露必要的接口给外部使用。
  5. 可读性和维护性

    • 类使得代码更加结构化,易于阅读和理解。
    • 当代码需要修改或扩展时,通过类的继承和多态等特性,开发者可以更加容易地实现这些需求。

二、继承和作用

  1. 代码复用

    • 继承允许子类重用父类的代码,包括属性和方法。
    • 通过继承,子类可以继承父类的所有功能,而无需重新编写这些功能。
  2. 代码扩展

    • 继承允许子类在父类的基础上添加新的功能或修改现有功能。
    • 通过重写父类的方法或添加新的方法,子类可以扩展父类的功能。
  3. 多态性

    • 继承使得子类能够以不同的方式实现父类中的方法。
    • 通过多态性,开发者可以在不修改现有代码的情况下,使用不同的子类来实现不同的行为。
  4. 层次结构

    • 继承允许开发者创建具有层次结构的类体系。
    • 在这种体系中,每个类都可以被视为一个特定类型的对象,而子类则是对该类型的进一步细化或扩展。
  5. 抽象和封装

    • 通过继承,开发者可以将通用的功能抽象到父类中,而将特定的功能封装到子类中。
    • 这有助于减少代码冗余,提高代码的可维护性和可扩展性。

在JavaScript中,类和继承的引入使得开发者能够以更加面向对象的方式编写代码,从而提高了代码的可读性、可维护性和可扩展性。同时,通过类的封装和继承等特性,开发者可以更加容易地实现代码的重用和扩展。

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

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

相关文章

旅游系统旅游小程序PHP+Uniapp

旅游门票预订系统,支持景点门票、导游产品便捷预订、美食打卡、景点分享、旅游笔记分享等综合系统 更新日志 V1.3.0 1、修复富文本标签 2、新增景点入驻【高级版本】3、新增门票核销【高级版】4、新增门票端口【高级版】

【日常笔记】Spring boot:编写 Content type = ‘text/plain‘ 接口

一、项目场景: 接口:Context-Type:text/plain 方式:POST 项目场景:硬件回调接口 二、实战 PostMapping(value "/xx/xxx", consumes "text/plain" ) 2.1、接口 /*** return String* time 202…

STM32F407+LAN8720A +LWIP +FreeRTOS UDP通讯

STM32F407+LAN8720A +LWIP +FreeRTOS ping通 上一篇实现了LWIP ping 通 本篇实现UDP通讯 实现如下功能: 串口1空闲中断+DMA接收,收到数据用UDP发送UDP接收,收到数据用串口1发送STM32CUBEIDE配置和代码 1. 配置UARAT1的空闲中断+DMA接收 UART1接收到数据,释放信号量,在任…

KeyFormer:使用注意力分数压缩KV缓存

Keyformer: KV Cache Reduction through Key Tokens Selection for Efficient Generative Inference 202403,发表在Mlsys Introduction 优化KV cache的策略,主要是集中在系统级别的优化上,比如FlashAttention、PagedAttention,它…

3.9 网际控制报文协议ICMP

欢迎大家订阅【计算机网络】学习专栏,开启你的计算机网络学习之旅! 文章目录 前言1 ICMP报文的封装2 ICMP差错报告报文的类型3 不应发送ICMP差错报告报文的情况4 常用的ICMP询问报文类型5 ICMP的应用 前言 网际控制报文协议(ICMP&#xff09…

东北大学《2024年839自动控制原理真题》 (完整版)

本文内容,全部选自自动化考研联盟的:《东北大学839自控考研资料》的真题篇。后续会持续更新更多学校,更多年份的真题,记得关注哦~ 目录 2024年真题 Part1:2024年完整版真题 2024年真题

百度智能云千帆AppBuilder升级,百度AI搜索组件上线,RAG支持无限容量向量存储!

百度智能云千帆 AppBuilder 发版升级! 进一步降低开发门槛,落地大模型到应用的最后一公里。在千帆 AppBuilder 最新升级的 V1.1版本中,企业级 RAG 和 Agent 能力再度提升,同时组件生态与应用集成分发更加优化。 • 企业级 RAG&am…

就业相关(硕士)

一、嵌入式 1.机器人行业 1.1 大致情况 要做机器人行业,主要技术栈是运动控制、深度学习、强化学习、具身智能等,主要求职方向有运动控制算法工程师和机器人算法工程师等等。大致薪资在30w到50w不等,主要看方向(双211&#xff…

Selenium操作指南

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 大家好,今天带大家一起系统的学习下模拟浏览器运行库Selenium,它是一个用于Web自动化测试及爬虫应用的重要工具。 Selenium测试直接运行在…

OpenCV相机标定与3D重建(11)用于在图像上绘制世界坐标系的三条轴函数drawFrameAxes()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 从姿态估计绘制世界/物体坐标系的轴。 cv::drawFrameAxes 是 OpenCV 库中的一个函数,用于在图像上绘制世界坐标系的三条轴&#xff0…

spring学习(XML中定义与配置bean(超详细)。IoC与DI入门spring案例)

目录 一、配置文件(XML)中定义与配置bean。 (1)bean的基础配置。(id、class) (2)bean的别名配置。 1、基本介绍。 2、demo测试。 3、NoSuchBeanDefinitionException! (3)…

Docker容器编排与Docker Compose

1. Docker Compose介绍与基础概念 Docker Compose是一个用于定义和运行多容器Docker应用的工具。通过Compose,用户可以用YAML文件来定义多个容器的服务、网络、存储等配置,并通过一个命令来启动、停止和管理这些容器。它简化了多容器应用的管理&#xf…

鸿蒙项目云捐助第七讲鸿蒙App应用的首页推荐模块布局的实现

鸿蒙项目云捐助第七讲鸿蒙App应用的首页推荐模块布局的实现 最后设置首页的推荐模块,参考模板如下图所示。 一、首页热门推荐模块的实现 对于热门推荐模块,先有上面的小标题栏,这里的标题栏也有一个小图标,首先从“百度图库”中…

MySQL八股-MVCC入门

文章目录 当前读(加锁)快照读(不加锁)MVCC隐藏字段undo-log版本链A. 第一步B.第二步C. 第三步 readview MVCC原理分析RCA. 先来看第一次快照读具体的读取过程:B. 再来看第二次快照读具体的读取过程: RR隔离级别 当前读…

基于单片机的无绳跳绳设计

基于单片机设计了一款无绳跳绳,采用传感器代替了绳子的摆动,从而实现了模拟跳绳的功能。其研究的方法是:以单片机作为这次设计的核心,它的外围包含有传感器模块、按键模块、显示模块、语音播报模块及电源模块等。本设计采用STM32芯…

【图像处理】利用numpy实现直方图均衡、自适应直方图均衡、对比度受限自适应直方图均衡

直方图均衡化是一种在图像处理技术,通过调整图像的直方图来增强图像的对比度。 本博客不利用opencv库,仅利用numpy、matplotlib来实现直方图均衡、自适应直方图均衡、对比度受限自适应直方图均衡 直方图均衡 包括四个流程 计算图像RGB三通道的归一化直…

Azure Function流式返回

最近用azure function做了一个api和llm交互,需要流式返回。但是默认不支持流返回,搜索了一下。记录。 官方文档:https://techcommunity.microsoft.com/blog/azurecompute/azure-functions-support-for-http-streams-in-python-is-now-in-prev…

【软件工程】简答题系列(一)(山东大学·软院考试专属)

🌈 个人主页:十二月的猫-CSDN博客 🔥 系列专栏: 🏀软件开发必练内功_十二月的猫的博客-CSDN博客 💪🏻 十二月的寒冬阻挡不了春天的脚步,十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前…

WebGIS城市停水及影响范围可视化实践

目录 前言 一、相关信息介绍 1、停水信息的来源 2、停水包含的相关信息 二、功能简介 1、基础小区的整理 2、停水计划的管理 三、WebGIS空间可视化 1、使用到的组件 2、停水计划的展示 3、影响小区的展示 4、实际效果 四、总结 前言 城市停水,一个看似…

数据结构,链表的简单使用

任意位置删除&#xff1a; void Any_Del(LinkListPtr h,int a)//任意删 {if(NULLh||a>h->len){printf("删除失败");}LinkListPtr ph;for(int i0;i<a-1;i){pp->next;}LinkListPtr p2p;p2p2->next;p->nextp->next->next;free(p2);p2NULL;h-&g…