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

文章目录

    • 概述
      • 一、类(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.mzph.cn/web/63117.shtml

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

相关文章

前端搭建企业级项目的具体步骤?

‌前端搭建企业级项目的具体步骤如下‌: ‌确定项目技术栈和规划项目结构‌:首先,确定使用的前端框架,如Vue.js,并规划项目的目录结构,包括src、components、routes、store等‌。 ‌准备开发环境‌&#x…

Less和SCSS,哪个更好用?

前言 Less 和 SCSS 都是流行的 CSS 预处理器,它们的目的都是扩展 CSS 的功能,使样式表更具组织性、可维护性和可重用性。虽然它们有许多相似之处,但在语法、特性和工作方式上也存在一些差异。 Less Less 是一种动态样式表语言,…

【第三节】Git 基本操作指南

目录 前言 一、获取与创建项目 1.1 git init 1.2 git clone 二、基本快照操作 2.1 git add 2.2 git status 2.3 git diff 2.4 git commit 2.5 git reset HEAD 三、 文件管理 3.1 git rm 3.2 git mv 四、 总结 前言 本文将详细介绍 Git 的基本操作,包括…

【Graylog】索引别名deflector的异常处理和索引分片数限制解除

索引别名deflector的异常处理 官方推荐处理步骤 Stop all Graylog nodes (OPTIONAL) If you want to keep the already ingested messages, reindex them into the Elasticsearch index with the greatest number, e. g. graylog_23 if you want to fix the deflector graylo…

PyTorch 2.0 以下版本中设置默认使用 GPU 的方法

PyTorch 2.0 以下版本中设置默认使用 GPU 的方法 在 PyTorch 2.0以下版本中,默认情况下仍然是使用 CPU 进行计算,除非明确指定使用 GPU。在 PyTorch 2.0 以下版本中,虽然没有 torch.set_default_device 的便捷方法,但可以通过显式…

【一本通】输入两个不同的数,通过指针对两个数进行相加和相乘

【一本通】输入两个不同的数,通过指针对两个数进行相加和相乘 C语言代码C代码Java代码 💐The Begin💐点点关注,收藏不迷路💐 输入两个不同的数,通过指针对两个数进行相加和相乘,并输出。 输入 …

X.game解析柚子币提升速效双向利好和年中历史新低原因

柚子币最新消息,币安宣布将于2024年9月25日21:00左右暂停柚子币网络上的代币存取业务,以全力支持即将到来的柚子币网络升级和硬分叉,这一消息为柚子币的未来发展增添了新的期待和变数。 除了速度的提升,Spring1.0还带来了诸多技术…

redis集群安装部署 redis三主三从集群

redis集群安装部署 redis三主三从集群 1、下载redis2、安装redis集群 三主三从3、配置redis开机自启动3.1、建立启动脚本3.2、复制多份redis启动脚本给集群使用3.3、添加可执行权限3.4、配置开机自启动 1、下载redis 本次redis安装部署选择当前最新的稳定版本7.4.1 下载链接: …

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

任意位置删除&#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…

Servlet容器来扫描指定包中的类 找到带有WebServlet注解的类

项目框架如上图 myweb下边三个类 package com.qcby.tomcat.myweb;import com.qcby.tomcat.webServlet.WebServlet;WebServlet(urlPatterns {"MyFirstServlet"}) public class MyFirstServlet {}package com.qcby.tomcat.myweb;import com.qcby.tomcat.webServlet.W…

clickhouse 查询优化思路

最重要的是要学会看懂explain &#xff0c;尤其是下推创建表时&#xff0c;可以选择表为分布式表。多个表join &#xff0c;创建表时根据join 字段,进行分片&#xff0c;让数据在同一个节点进行join &#xff0c;提高join 效率。多个表join , 通过创建物化视图的方式&#xff0…

两数之和(Hash表)

优质博文&#xff1a;IT-BLOG-CN 一、题目 给定一个整数数组nums和一个整数目标值target&#xff0c;请你在该数组中找出"和"为目标值target的那两个整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元…

C++8--赋值运算符重载

1.运算符重载 C引入运算符的目的是为了增强代码的可读性。运算符重载是具有特殊函数名的函数&#xff0c;也具有其返回值类型&#xff0c;函数名字以及参数列表&#xff0c;其返回值类型与参数列表与普通的函数相似。 函数名字为&#xff1a;关键字operator后面接需要重载的运算…

P1255 数楼梯

刚开始使用暴力进行求解&#xff0c;结果发现这是一道考验高精度的题目&#xff0c;后来用高精度的方法&#xff0c;甚至使用到了容器&#xff0c;结果还不如暴力求解的60分&#xff0c;后来看了题解&#xff0c;有一个非常好的思路&#xff0c;即体现了高精度求和&#xff0c;…

pyfink1.20版本下实现消费kafka中数据并实时计算

1、环境 JDK版本&#xff1a;1.8.0_412python版本&#xff1a;3.10.6apache-flink版本&#xff1a;1.20.0flink版本&#xff1a;1.20kafka版本&#xff1a;kafka_2.12-3.1.1flink-sql-connector-kafka版本&#xff1a;3.3.0-1.202、执行python-flink脚本 从kafka的demo获取消…

数据结构速成

1. 数据结构与算法 2. 顺序表 3. 链表 4. 栈与队列 5. 串 6. 树与二叉树&#xff08;1&#xff09; 7. 树与二叉树&#xff08;2&#xff09; 8. 图 9. 图的应用 10. 查找 11. 排序&#xff08;1&#xff09; 12. 排序&#xff08;2&#xff09;

k8s的污点与容忍度

污点&#xff08;Taint&#xff09;针对节点来说&#xff0c;和节点亲和性正好相对&#xff0c;节点亲和性使Pod被吸引到一类特定的节点&#xff0c;而污点则使节点能够排斥一类特定的Pod。 容忍度&#xff08;Toleration&#xff09;应用于Pod上&#xff0c;它用来允许调度器…

how to write 述职pptx as a tech manager

As a technical manager, crafting an effective 述职 (performance review) PPT requires you to highlight your leadership, team accomplishments, technical contributions, challenges faced, and future plans. Heres a structured approach to design your PPT: 1. Cov…

从源码层级深入探索 Spring AMQP 如何在 Spring Boot 中实现 RabbitMQ 集成——消费者如何进行消费

本章节主要从底层源码探索Spring Boot中RabbitMQ如何进行消费&#xff0c;至于RabbitMQ是如何使用如何生产消息&#xff0c;本章不做过多介绍&#xff0c;感兴趣的小伙伴可以参考&#xff1a;从源码层级深入探索 Spring AMQP 如何在 Spring Boot 中实现 RabbitMQ 集成——生产者…

计算机视觉中的边缘检测算法

摘要&#xff1a; 本文全面深入地探讨了计算机视觉中的边缘检测算法。首先阐述了边缘检测的重要性及其在计算机视觉领域的基础地位&#xff0c;随后详细介绍了经典的边缘检测算法&#xff0c;包括基于梯度的 Sobel 算子算法、Canny 边缘检测算法等&#xff0c;深入剖析了它们的…