优雅而高效的JavaScript—— Class 和模块化

news2025/3/13 13:54:23

在这里插入图片描述
😊博主:小猫娃来啦
😊文章核心:优雅而高效的JavaScript—— Class 和模块化

文章目录

  • 引言
  • Class 的概念和用法
    • Class 的定义
    • Class 的继承
    • Class 的静态方法和属性
  • 模块化的概念和用法
    • 模块的导出和导入
    • 模块的默认导出和命名导出
    • 模块的循环依赖问题
  • Class 和模块化的结合应用
    • 使用 Class 和模块化实现一个简单的计算器
    • 使用 Class 和模块化实现一个简单的购物车
  • 总结

引言

在过去,JavaScript 是一门基于原型的面向对象编程语言,没有 Class 和模块化的概念。这导致了代码的组织结构混乱,难以维护和扩展。ES6 引入了 Class 和模块化的概念,使得 JavaScript 可以更加面向对象,具备模块化的组织结构。本文将介绍 Class 和模块化的概念和用法,并通过示例代码演示其应用。


Class 的概念和用法

Class 的定义

Class 是一种用于创建对象的模板或蓝图。通过 Class,我们可以定义对象的属性和方法,并通过实例化来创建具体的对象。

示例代码:

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  
  sayHello() {
    console.log(`Hello, my name is ${this.name}.`);
  }
}

const person = new Person("John", 25);
person.sayHello(); // 输出:Hello, my name is John.

在上面的示例中,我们定义了一个名为 Person 的 Class,它有两个属性 name 和 age,以及一个方法 sayHello。通过 new 关键字可以创建 Person 的实例,并调用其方法。

Class 的继承

Class 支持继承,子类可以继承父类的属性和方法,并可以重写或扩展它们。

示例代码:

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

class Dog extends Animal {
  speak() {
    console.log(`${this.name} barks.`);
  }
}

const dog = new Dog("Bobby");
dog.speak(); // 输出:Bobby barks.

在上面的示例中,我们定义了一个 Animal 的父类和一个 Dog 的子类。子类 Dog 继承了父类 Animal 的属性和方法,并重写了 speak 方法。通过创建 Dog 的实例,我们可以调用子类的方法。

Class 的静态方法和属性

Class 还支持静态方法和属性,它们可以直接通过类名调用,而不需要创建实例。

示例代码:

class MathUtils {
  static add(a, b) {
    return a + b;
  }
  
  static PI = 3.14159;
}

console.log(MathUtils.add(1, 2)); // 输出:3
console.log(MathUtils.PI); // 输出:3.14159

在上面的示例中,我们定义了一个 MathUtils 的类,它有一个静态方法 add 和一个静态属性 PI。我们可以直接通过类名调用这些静态方法和属性,而不需要创建实例。


模块化的概念和用法

模块的导出和导入

模块化是一种将代码分割成独立的模块,并通过导出和导入来共享和使用这些模块的方式。ES6 引入了模块化的语法,使得 JavaScript 可以更好地组织和管理代码。

示例代码:
在一个名为 utils.js 的模块中,我们导出了两个函数 add 和 subtract:

export function add(a, b) {
  return a + b;
}

export function subtract(a, b) {
  return a - b;
}

在另一个文件中,我们通过 import 关键字导入这些函数,并使用它们:

import { add, subtract } from './utils.js';

console.log(add(1, 2)); // 输出:3
console.log(subtract(3, 2)); // 输出:1

在上面的示例中,我们将 add 和 subtract 函数导出为 utils.js 模块的一部分,并通过 import 关键字在另一个文件中导入并使用它们。

模块的默认导出和命名导出

除了导出多个函数或变量,我们还可以通过默认导出来导出一个默认的函数或变量。

示例代码:
在一个名为 utils.js 的模块中,我们默认导出了一个函数 multiply:

export default function multiply(a, b) {
  return a * b;
}

在另一个文件中,我们通过 import 关键字导入默认导出的函数,并使用它:

import multiply from './utils.js';

console.log(multiply(2, 3)); // 输出:6

在上面的示例中,我们将 multiply 函数默认导出为 utils.js 模块的一部分,并通过 import 关键字在另一个文件中导入并使用它。

模块的循环依赖问题

在模块化的代码中,循环依赖是一个常见的问题。循环依赖指的是两个或多个模块之间相互依赖,形成了一个循环的依赖关系。

示例代码:
在一个名为 moduleA.js 的模块中,我们导入了 moduleB.js 模块,并使用其中的函数:

import { foo } from './moduleB.js';

export function bar() {
  console.log(foo());
}

在另一个文件 moduleB.js 中,我们导入了 moduleA.js 模块,并使用其中的函数:

import { bar } from './moduleA.js';

export function foo() {
  return 'Hello from moduleB.js';
}

bar();

在上面的示例中,moduleA.js 导入了 moduleB.js 的 foo 函数,而 moduleB.js 导入了 moduleA.js 的 bar 函数。这样就形成了一个循环的依赖关系,导致代码无法正确执行。

为了解决循环依赖的问题,我们可以将依赖关系改为单向的,或者使用其他的解决方案,如在模块的顶部导入。


Class 和模块化的结合应用

使用 Class 和模块化实现一个简单的计算器

// calculator.js
export class Calculator {
  add(a, b) {
    return a + b;
  }
  
  subtract(a, b) {
    return a - b;
  }
}

// main.js
import } from './calculator.js';

const calculator = new Calculator();
console.log(calculator.add(1, 2)); // 输出:3
console.log(calculator.subtract(3, 2)); // 输出:1

在上面的示例中,我们定义了一个 Calculator 的 Class,并导出它。在另一个文件中,我们通过导入 Calculator,并创建它的实例,来使用其中的方法。

使用 Class 和模块化实现一个简单的购物车

// product.js
export class Product {
  constructor(name, price) {
    this.name = name;
    this.price = price;
  }
}

// cart.js
export class Cart {
  constructor() {
    this.products = [];
  }
  
  addProduct(product) {
    this.products.push(product);
  }
  
  getTotalPrice() {
    return this.products.reduce((total, product) => total + product.price, 0);
  }
}

// main.js
import { Product } from './product.js';
import { Cart } from './cart.js';

const cart = new Cart();
const product1 = new Product("Apple", 1);
const product2 = new Product("Banana", 2);

cart.addProduct(product1);
cart.addProduct(product2);

console.log(cart.getTotalPrice()); // 输出:3

在上面的示例中,我们定义了一个 Product 的 Class 和一个 Cart 的 Class,并导出它们。在另一个文件中,我们通过导入 Product 和 Cart,并创建它们的实例,来实现一个简单的购物车功能。


总结

ES6 引入了 Class 和模块化的概念,使得 JavaScript 可以更加面向对象,具备模块化的组织结构。Class 允许我们使用面向对象的方式来定义和实例化对象,而模块化则提供了一种组织和管理代码的方式。通过 Class 和模块化,我们可以更好地组织和管理代码,提高代码的可维护性和可扩展性。在实际开发中,我们可以使用 Class 和模块化来实现各种功能,如计算器、购物车等。

在这里插入图片描述


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

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

相关文章

SpringCloud: sentinel链路限流

一、配置文件要增加 spring.cloud.sentinel.webContextUnify: false二、在要限流的业务方法上使用SentinelResource注解 package cn.edu.tju.service;import com.alibaba.csp.sentinel.annotation.SentinelResource; import com.alibaba.csp.sentinel.slots.block.BlockExcept…

CVPR、ICCV、ECCV论文获取

CVPR每年召开,ICCV两年一次 链接地址 ECCV两年一开 链接地址

10. 机器学习-评测指标

Hi,你好。我是茶桁。 之前的课程中,我们学习了两个最重要的回归方法,一个线性回归,一个逻辑回归。也讲解了为什么学习机器学习要从逻辑回归和线性回归讲起。因为我们在解决问题的时候,有限选择简单的假设,越复杂的模型…

十七、文件(1)

本章概要 文件和目录路径 选取路径部分片段路径分析Paths 的增减修改 目录 在丑陋的 Java I/O 编程方式诞生多年以后,Java终于简化了文件读写的基本操作。 打开并读取文件对于大多数编程语言来说是非常常用的,由于 I/O 糟糕的设计以至于很少有人能够在不…

第七章 排序

第七章 排序 概述插入排序交换排序冒泡排序快速排序 选择排序直接选择排序堆排序 归并排序有序序列合并二路归并排序 小试牛刀 概述 排序就是将一组对象按照规定的次序(升序或降序等)重新排列的过程,往往为检索服务相同键值的两个记录在排序…

索引背后的数据结构——B+树

为什么要使用B树? 可以进行数据查询的数据结构有二叉搜索树、哈希表等。对于前者来说,树的高度越高,进行查询比较的时候访问磁盘的次数就越多。而后者只有在数据等于key值的时候才能进行查询,不能进行模糊匹配。所以出现了B树来解…

SQL数据库管理工具RazorSQL mac中文版特点与功能

RazorSQL mac是一款功能强大的SQL数据库管理工具,它支持多种数据库,包括MySQL、Oracle、Microsoft SQL Server、SQLite、PostgreSQL等。 RazorSQL mac 软件特点和功能 多种数据库支持:RazorSQL支持多种数据库,用户可以通过一个工…

故障预测与健康管理(PHM)在工业领域的发展前景

故障预测与健康管理(PHM)作为一种关键技术,已经在工业领域引起了广泛的关注和应用。PHM利用传感器、数据科学和智能算法等技术手段,通过实时监测和分析设备和系统的状态,提前发现潜在故障,并采取适当的维修…

制作linux系统内部yum源仓库

需求说明 制作内网linux系统yum源仓库,比较简单的方式就是添加系统镜像,此种yum配置方式可参考文章 https://blog.csdn.net/d1240673769/article/details/108477661 如果无法提供系统镜像,那该如何创建内网的yum源仓库呢?本文提…

互联网Java工程师面试题·Java 总结篇·第六弹

目录 56、TreeMap 和 TreeSet 在排序时如何比较元素?Collections 工具类中的 sort()方法如何比较元素? 57、Thread 类的 sleep()方法和对象的 wait()方法都可以让线程暂停执行,它们有什么区别? 58、线程的 sleep()方法和 yield()方法有什…

在nodejs中实现双重身份验证机制

在nodejs中实现双重身份验证机制 双重身份验证(Two-factor authentication)是一种安全机制,它要求用户提供两种不同的身份验证因素来访问他们的帐户:密码和发送到他们的移动设备的验证码。在本文中,我们将一步步通过使用speakeasy在nodejs中实…

deforum + kandinsky = 视频工作流

像搭积木一样玩AI,随着模型种类的不断丰富,不同的组合会带来什么惊喜?今天和大家分享最近看到的一个视频工作流(工具箱)。 首先,我们先对deforum和kandinsky做一些基本的介绍: deforum-art/defo…

【论文解读】单目3D目标检测 CUPNet(ICCV 2021)

本文分享单目3D目标检测,CUPNet 模型的论文解读,了解它的设计思路,论文核心观点,模型结构,以及效果和性能。 目录 一、CUPNet简介 二、论文核心观点 三、模型框架 四、损失函数 五、核心观点——3D高度估计误差 引…

Python之并发编程(进程)

文章目录 一、操作系统的发展史二、进程基础(操作系统中的概念)1.什么是进程2.进程的调度算法3.进程的并行与并发4.进程的三状态5.同步异步6.阻塞与非阻塞7.同步异步与阻塞非阻塞综合使用 三、如何创建进程Process的几个方法如何开启多进程进程间的数据默认隔离基于TCP协议的高…

【Qt控件之QButtonGroup】概述及使用

概述 QButtonGroup 类提供了一个容器来组织一组按钮部件。 QButtonGroup 提供了一个抽象容器,可以将按钮部件放置其中。它不提供此容器的可视表示(请参见 QGroupBox,用于容器部件),而是管理组中每个按钮的状态。 一个…

Electron webview 内网页 与 preload、 渲染进程、主进程的常规通信 以及企业级开发终极简化通信方式汇总

Electron 嵌入的页面中注入的是 preload.js 通过在标签中给 prelaod赋值,这里提到了 file://前缀,以及静态目录 static 怎么获取 实际代码,其中__static就是我们存放静态文件的地方,这个 static 是 electron 源代码根目录下的文件…

使用unordered_write调优RocksDB写性能

在使用rocksdb存储的服务中,我们发现QPS在4w/s就怎么调整都上不去了,写性能受到了某种限制。为什么呢?下图描述了rocksdb写入的流程。我们发现 unordered_write true可以提高写入吞吐量。 rocksdb的数据正常写入流程是,多个线程形…

九月 NFT 行业解读:熊市情绪仍占上风

作者: stellafootprint.network 9 月,著名主流媒体《滚石》(Rolling Stone)发表了一篇题为《你的 NFT 实际上——终于——完全不值钱了》(Your NFTs Are Actually — Finally — Totally Worthless)的文章&#xff0c…

【网络编程】从网络编程、TCP/IP开始到BIO、NIO入门知识(未完待续...)

目录 前言前置知识一、计算机网络体系结构二、TCP/IP协议族2.1 简介*2.2 TCP/IP网络传输中的数据2.3 地址和端口号2.4 小总结 三、TCP/UDP特性3.1 TCP特性TCP 3次握手TCP 4次挥手TCP头部结构体 3.2 UDP特性 四、总结 课程内容一、网络通信编程基础知识1.1 什么是Socket1.2 长连…

NumPy基础及取值操作

目录 第1关:ndarray对象 相关知识 怎样安装NumPy 什么是ndarray对象 如何实例化ndarray对象 使用array函数实例化ndarray对象 使用zeros,ones,empty函数实例化ndarray对象 代码文件 第2关:形状操作 相关知识 怎样改变n…