”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 提升你的 JavaScript:深入研究面向对象编程✨

提升你的 JavaScript:深入研究面向对象编程✨

发布于2024-11-07
浏览:381

Elevate Your JavaScript: A Deep Dive into Object-Oriented Programming✨

面向对象编程 (OOP) 是一种强大的范例,它彻底改变了我们构建和组织代码的方式。

虽然 JavaScript 最初是一种基于原型的语言,但它已经发展到接受 OOP 原则,特别是随着 ES6 的引入和后续更新。

这篇文章深入研究了 JavaScript 中 OOP 的核心概念,探索如何实现它们来创建更健壮、可维护和可扩展的应用程序。

我们将了解 OOP 的四大支柱 - 继承、抽象、封装和多态性 - 演示如何在 JavaScript 中应用每个原则。在此过程中,我们将研究现实世界的示例并讨论每个概念的优缺点。

无论您是希望提高 JavaScript 中 OOP 技能的经验丰富的开发人员,还是渴望掌握这些基本概念的新手,本指南都将为您在 JavaScript 项目中利用 OOP 的力量提供宝贵的见解。


1。遗产:

继承允许一个类从另一个类继承属性和方法。它提高了代码的可重用性并建立了父类和子类之间的关系。

class Vehicle {
  constructor(make, model) {
    this.make = make;
    this.model = model;
  }

  getInfo() {
    return `${this.make} ${this.model}`;
  }

  start() {
    return "The vehicle is starting...";
  }
}

class Car extends Vehicle {
  constructor(make, model, doors) {
    super(make, model);
    this.doors = doors;
  }

  getCarInfo() {
    return `${this.getInfo()} with ${this.doors} doors`;
  }
}

const myCar = new Car("Toyota", "Corolla", 4);
console.log(myCar.getCarInfo()); // Output: Toyota Corolla with 4 doors
console.log(myCar.start()); // Output: The vehicle is starting...

在此示例中,Car 继承自 Vehicle,获取对其属性和方法的访问权限。

优点:

  • 代码可重用性:子类继承父类的属性和方法。

  • 在对象之间建立清晰的层次结构。

  • 允许方法重写和扩展。

缺点:

  • 可能导致父类和子类之间的紧密耦合。

  • 深层继承层次结构可能会变得复杂且难以维护。


2.抽象

抽象涉及隐藏复杂的实现细节并仅显示对象的必要特征。在 JavaScript 中,我们可以使用抽象类(尽管本身不支持)和接口来实现抽象。

class Shape {
  constructor() {
    if (new.target === Shape) {
      throw new TypeError("Cannot instantiate abstract class");
    }
  }

  calculateArea() {
    throw new Error("Method 'calculateArea()' must be implemented.");
  }
}

class Circle extends Shape {
  constructor(radius) {
    super();
    this.radius = radius;
  }

  calculateArea() {
    return Math.PI * this.radius ** 2;
  }
}

class Rectangle extends Shape {
  constructor(width, height) {
    super();
    this.width = width;
    this.height = height;
  }

  calculateArea() {
    return this.width * this.height;
  }
}

// const shape = new Shape(); // Throws TypeError
const circle = new Circle(5);
const rectangle = new Rectangle(4, 6);

console.log(circle.calculateArea()); // Output: 78.53981633974483
console.log(rectangle.calculateArea()); // Output: 24

在此示例中,Shape 充当无法直接实例化的抽象类。它定义了所有子类都必须实现的公共接口calculateArea。这种抽象允许我们通过通用接口处理不同的形状,而不必担心它们的具体实现。

优点:

  • 通过隐藏不必要的细节来简化复杂的系统。

  • 提高代码可维护性并减少重复。

  • 允许关注对象做什么而不是它如何做。

缺点:

  • 如果设计不仔细,可能会导致过度简化。

  • 在某些情况下可能会带来性能开销。


3.封装

封装是将数据和在单个单元(对象)内操作该数据的方法捆绑在一起。在 JavaScript 中,我们可以使用闭包和符号来创建私有属性和方法。

class BankAccount {
  #balance = 0;  // Private field

  constructor(owner) {
    this.owner = owner;
  }

  deposit(amount) {
    if (amount > 0) {
      this.#balance  = amount;
      return true;
    }
    return false;
  }

  withdraw(amount) {
    if (amount > 0 && this.#balance >= amount) {
      this.#balance -= amount;
      return true;
    }
    return false;
  }

  getBalance() {
    return this.#balance;
  }
}

const account = new BankAccount('John Doe');
account.deposit(1000);
console.log(account.getBalance()); // Output: 1000
console.log(account.#balance); // SyntaxError: Private field '#balance' must be declared in an enclosing class

在此示例中,#balance 是私有字段,无法从类外部直接访问。

优点:

  • 数据保护:防止未经授权访问内部数据。

  • 模块化:将相关功能捆绑在一起。

  • 更容易维护:内部实现的更改不会影响外部代码。

缺点:

  • 由于缺乏真正的私有成员,在 JavaScript 中实现起来可能很复杂。

  • 创建 getter 和 setter 时可能会导致冗长的代码。


4。多态性

多态性允许将不同类的对象视为公共超类的对象。在 JavaScript 中,这可以通过方法重写来实现。

class Animal {
  speak() {
    return "The animal makes a sound";
  }
}

class Dog extends Animal {
  speak() {
    return "The dog barks";
  }
}

class Cat extends Animal {
  speak() {
    return "The cat meows";
  }
}

const animals = [new Animal(), new Dog(), new Cat()];

animals.forEach(animal => {
  console.log(animal.speak());
});

// Output:
// The animal makes a sound
// The dog barks
// The cat meows

在这个例子中,每个类以不同的方式实现speak方法,展示了多态性。

优点:

  • 灵活性:不同类型的对象可以统一处理。

  • 可扩展性:可以在不更改现有代码的情况下添加新类。

  • 通过允许对不同类型使用单一接口来简化代码。

缺点:

  • 如果过度使用,会使代码更难调试。

  • 在某些语言中可能会导致性能开销(在 JavaScript 中较少)。


正如我们所探索的,JavaScript 中的面向对象编程提供了一个强大的工具包,用于创建结构化、可维护和可扩展的代码。 OOP 的四大支柱 - 继承、抽象、封装和多态性 - 每一个都带来独特的优势,允许开发人员建模复杂的系统、保护数据完整性、促进代码重用以及创建灵活、可扩展的应用程序。

虽然由于语言的独特特性,在 JavaScript 中实现这些原则有时可能需要创造性的方法,但好处是显而易见的。 OOP 可以使代码库更有组织性、团队成员之间的协作更轻松,并提高对不断变化的需求的适应性。

然而,重要的是要记住 OOP 并不是一种万能的解决方案。每个项目可能需要对这些原则进行不同的平衡,并且在某些情况下,其他范例可能更合适。关键是要彻底理解这些概念并明智地应用它们,始终牢记您的项目和团队的具体需求。

快乐编码?

版本声明 本文转载于:https://dev.to/alaa-samy/elevate-your-javascript-a-deep-dive-into-object-oriented-programming-2080?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • Copilotkit:您的编码冒险人工智能僚机
    Copilotkit:您的编码冒险人工智能僚机
    简介:当人工智能遇见代码(火花四溅) 在不断发展的科技世界中,算法起舞,数据流歌唱,镇上出现了一位新玩家:Copilotkit。这就像有一个非常聪明的朋友,他从不睡觉,不会喝掉你所有的咖啡,也不会因为你凌晨 3 点穿着睡衣编码而评判你。欢迎来到编码的未来,人工智能不仅是辅助,而且是...
    编程 发布于2024-11-08
  • 如何修复 Mac 上的 Java 8 安装问题
    如何修复 Mac 上的 Java 8 安装问题
    解决 Mac 上 Java 8 的安装问题您关于 Mac 上 Java 8 安装文件的意外位置和兼容性挑战的查询重点开发商面临的共同问题。本文旨在提供一个全面的解决方案来解决这些问题。安装异常Oracle的Java安装程序倾向于将Java 8文件放在/Library/Java/JavaVirtual...
    编程 发布于2024-11-08
  • 在空数据集上使用 MySQL 的 SUM 函数时如何返回“0”而不是 NULL?
    在空数据集上使用 MySQL 的 SUM 函数时如何返回“0”而不是 NULL?
    当不存在任何值时如何从 MySQL 的 SUM 函数中检索“0”MySQL 中的 SUM 函数提供了一种方便的方法来聚合数值价值观。但是,当查询期间没有找到匹配的行时,SUM 函数通常返回 NULL 值。对于某些用例,可能更需要返回“0”而不是 NULL。利用 COALESCE 解决问题此问题的解决...
    编程 发布于2024-11-08
  • useMemo 与 useCallback
    useMemo 与 useCallback
    介绍 React 提供了广泛的钩子来帮助我们高效地构建动态应用程序。在这些钩子中,useMemo和useCallback是提高组件性能的重要工具。尽管两者都有相似的目的——防止不必要的重新计算或函数重新创建——但它们适用于不同的场景。 在本文中,我们将探讨 useMemo 和 us...
    编程 发布于2024-11-08
  • 为什么 MDM 很重要:优势和商业价值
    为什么 MDM 很重要:优势和商业价值
    在当今的数字经济中,数据是每个成功企业的基石。随着组织生成的信息呈指数级增长,主数据的有效管理已成为当务之急。主数据管理 (MDM) 是管理组织关键数据资产(例如客户信息、产品详细信息和财务记录)的战略流程,确保所有部门和系统的准确性、一致性和可访问性。但为什么 MDM 很重要?更重要的是,它能带来...
    编程 发布于2024-11-08
  • 是什么导致 Google Chrome 的 Console.log() 中数组和对象的行为不一致?
    是什么导致 Google Chrome 的 Console.log() 中数组和对象的行为不一致?
    Google Chrome 的 console.log() 表现出数组和对象不一致的行为了解问题在 Google Chrome 中调试代码时,观察到 console.log() 在处理嵌套数组时表现得很奇怪。记录数组时,在记录后修改其内部值会导致记录的输出反映更新后的值而不是记录时的值。 Firef...
    编程 发布于2024-11-08
  • 在 PHP 中按对象字段对对象数组进行排序
    在 PHP 中按对象字段对对象数组进行排序
    在 PHP 中,有多种方法可以按对象字段对对象数组进行排序。以下是一些常见的方法: 将 usort() 函数与自定义比较函数结合使用 实现自定义排序算法 利用 array_multisort() 函数 将 usort() 函数与自定义比较函数结合使用 以下是在 PHP 中使用 us...
    编程 发布于2024-11-08
  • 注意 Java 中的类型转换
    注意 Java 中的类型转换
    Java是强类型语言,但仍然可以在不同类型的原始变量之间传递值。例如,我可以将 int 的值分配给 double ,没有任何问题,只要接收该值的类型的存储容量可以处理它。 参见下面每个原始类型的大小: 将值转移到具有更大存储容量的类型有一个技术名称:“扩大转换”。该术语在葡萄牙语中通常被翻译为“放...
    编程 发布于2024-11-08
  • 如何在 React 中构建天气应用
    如何在 React 中构建天气应用
    If you want to master crucial web development skills like working with API's, fetching data, and asynchronous functions such as async and await in Rea...
    编程 发布于2024-11-08
  • Go 和 Python 之间的 gRPC 通信
    Go 和 Python 之间的 gRPC 通信
    gRPC 是一个功能强大、高性能的远程过程调用 (RPC) 框架,尽管不如 REST 常用,但在某些场景中提供了显着的优势。 此外,它与语言无关,可以在任何环境中运行,使其成为服务器到服务器通信的理想选择。 我不会深入研究它的完整解释,但这里是 gRPC 的一般链接。我将提供实践教程 ...
    编程 发布于2024-11-08
  • CSS 定位中的position:sticky 和position:fixed 有何不同?
    CSS 定位中的position:sticky 和position:fixed 有何不同?
    浏览 CSS 定位的细微差别:揭开position:sticky 和position:fixed理解 CSS 定位的复杂性可能具有挑战性,尤其是对于 CSS 新手。经常出现的一个特殊困境是position:sticky 和position:fixed 之间的区别。本文深入探讨了显着差异,为那些寻求更...
    编程 发布于2024-11-08
  • 如何使用 JavaScript 将大字符串拆分为 N 大小的块?
    如何使用 JavaScript 将大字符串拆分为 N 大小的块?
    在 JavaScript 中将大字符串拆分为 N 大小的块要有效地将大字符串拆分为大小为 N 的较小块,您可以使用JavaScript 中的 String.prototype.match 方法。此方法使您能够将正则表达式模式应用于字符串并提取匹配的子字符串。使用 String.prototype.m...
    编程 发布于2024-11-08
  • 如何在 C++ 中不使用 getline() 将文件字节读入字符数组?
    如何在 C++ 中不使用 getline() 将文件字节读入字符数组?
    How to Retrieve File bytes into a Char Array in C 要在不使用 getline() 的情况下将文件字节读入 char 数组,请考虑使用 ifstream::read()。请按照下列步骤操作:打开文件:std::ifstream infile("...
    编程 发布于2024-11-08
  • 以下是一些符合条件的标题选项:

**选项 1(关注问题):**

* **如何在 Python 中创建真正不可变的对象:超越基础**

**选项 2(突出显示解决方案)
    以下是一些符合条件的标题选项: **选项 1(关注问题):** * **如何在 Python 中创建真正不可变的对象:超越基础** **选项 2(突出显示解决方案)
    Python 中的不可变对象:超越基本解决方案虽然标准元组类提供了不可变性,但本文探讨了创建不可变对象的更高级技术重写 __setattr__:一种有限的方法一个常见的解决方案是重写 setattr 方法。但是,即使在 init 函数中,这也会阻止属性设置。因此,它可能并不适合所有场景。子类化元组:...
    编程 发布于2024-11-08
  • Spring Boot:如何解决跨源问题
    Spring Boot:如何解决跨源问题
    跨源问题描述 您可能会遇到以下错误消息: 被 CORS 策略阻止:请求的资源上不存在“Access-Control-Allow-Origin”标头 此错误表示对某个地址的请求已被 CORS 协议阻止,因为资源中缺少 Access-Control-Allow-Origin 标头。 ...
    编程 发布于2024-11-08

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3