08-Module Pattern 模块模式-vanilla篇

随着应用程序和代码库的增长,保持代码的可维护性和独立性变得越来越重要。模块模式使得代码分割成更小的、可重用的部分。 除了此之外,模块还允许您将文件中的某些值保持为私有。默认情况下,模块内的声明的范围到该模块。如果我们不显式导出某个值,则该值在该模块之外不可用。这降低了代码库其他部分中声明的值发生名称冲突的风险,因为这些值在全局范围内不可用。 ES2015 Modules ES2015 引入了内置 JavaScript 模块。模块是包含 JavaScript 代码的文件,与普通脚本相比,其行为存在一些差异。 让我们看一个名为 math.js 的模块示例,其中包含数学函数。 function add(x, y) { return x + y; } function multiply(x) { return x * 2; } function subtract(x, y) { return x - y; } function square(x) { return x * x; } 函数允许用户进行加法、乘法、减法以及获取他们传递的值的平方。 但是,我们不仅仅想在 math.js 文件中使用这些函数,我们希望能够在 index.js 文件中引用它们。但是直接在 index.js 文件内调用会抛出错误: index.js 文件中没有名为 add 、 subtract 、 multiply 或 square 。 为了使 math.js 中的函数可用于其他文件,我们首先必须将它们导出。为了从模块导出代码,我们可以使用 export 关键字。导出函数的一种方法是使用命名导出:我们只需在可公开的部分前面添加 export 关键字。在这种情况下,我们需要在每个函数前面添加 export 关键字,因为 index....

August 18, 2023 · 4 min · 653 words · Anna.me

07-Prototype Pattern 原型模式-vanilla篇

原型模式是在同一类型的许多对象之间共享属性的有用方法。原型是 JavaScript 原生的对象,可以通过原型链被对象访问。 在我们的应用程序中,我们经常需要创建许多相同类型的对象。想要达到此目的可以通过 ES6 类创建多个实例。 假设我们想创造很多狗,他们有一个名字,并且它们可以吠叫。 class Dog { constructor(name) { this.name = name; } bark() { return `Woof!`; } } const dog1 = new Dog("Daisy"); const dog2 = new Dog("Max"); const dog3 = new Dog("Spot"); 请注意这里 constructor 如何包含 name 属性,并且类本身如何包含 bark 属性。使用 ES6 类时,类本身定义的所有属性(在本例中为 bark )都会自动添加到 prototype 中。 我们可以通过访问构造函数上的 prototype 属性或通过任何实例上的 __proto__ 属性直接查看 prototype 。 console.log(Dog.prototype); // constructor: ƒ Dog(name, breed) bark: ƒ bark() console.log(dog1.__proto__); // constructor: ƒ Dog(name, breed) bark: ƒ bark() 构造函数的任何实例上的 __proto__ 值都是对构造函数原型的直接引用。每当我们尝试直接访问对象上不存在的对象属性时,JavaScript 就会沿着原型链向下查找该属性在原型链中是否可用。...

August 14, 2023 · 2 min · 227 words · Anna.me

06-Singleton Pattern 单例模式-vanilla篇

单例是可以实例化一次并可以全局访问的类。单一实例可以在我们的应用程序中共享,这使得单例非常适合管理应用程序中的全局状态。 首先,看一下使用 ES2015 类的单例是什么样子。对于这个例子,我们将构建一个 Counter 类,它具有: 返回实例值的 getInstance 方法 返回 counter 变量当前值的 getCount 方法 将 counter 的值增加 1 的 increment 方法 将 counter 的值减一的 decrement 方法 let counter = 0; class Counter { getInstance() { return this; } getCount() { return counter; } increment() { return ++counter; } decrement() { return --counter; } } 然而,这个类不符合 Singleton 的标准。 Singleton 应该只能被实例化一次。目前,我们可以创建 Counter 类的多个实例。 let counter = 0; class Counter { getInstance() { return this; } getCount() { return counter; } increment() { return ++counter; } decrement() { return --counter; } } const counter1 = new Counter(); const counter2 = new Counter(); console....

August 12, 2023 · 3 min · 507 words · Anna.me

05-Observer Pattern 观察者模式-vanilla篇

通过观察者模式,我们可以将某些对象(观察者)订阅到另一个称为可观察对象的对象。每当事件发生时,可观察者都会通知其所有观察者。 一个可观察对象通常包含 3 个重要部分: observers :观察者数组,每当特定事件发生时都会收到通知 subscribe() :将观察者添加到观察者列表的方法 unsubscribe() :从观察者列表中删除观察者的方法 notify() :每当特定事件发生时通知所有观察者的方法 创建一个简单的方法是使用 ES6 类。 class Observable { constructor() { this.observers = []; } subscribe(func) { this.observers.push(func); } unsubscribe(func) { this.observers = this.observers.filter((observer) => observer !== func); } notify(data) { this.observers.forEach((observer) => observer(data)); } } 我们现在可以使用 subscribe 方法将观察者添加到观察者列表中,使用 unsubscribe 方法删除观察者,并使用 notify 方法通知所有订阅者。 现在我们有一个非常基本的应用程序,仅包含两个组件: Button 和 Switch 。 export default function App() { return ( <div className="App"> <Button>Click me!</Button> <FormControlLabel control={<Switch />} /> </div> ); } 我们希望跟踪用户与应用程序的交互。每当用户单击按钮或切换开关时,我们都希望使用时间戳记录此事件。除了记录之外,我们还想创建一个 Toast 通知,每当事件发生时就会显示。...

August 5, 2023 · 2 min · 379 words · Anna.me

04-Mixin Pattern 混合模式-vanilla篇

mixin 是一个对象,我们可以使用它向另一个对象或类添加可重用的功能,而无需使用继承。我们不能单独使用 mixin:它们的唯一目的是在没有继承的情况下向对象或类添加功能。 假设我们的应用程序需要创建多只狗。然而,我们创建的基本狗除了 name 属性之外没有任何属性。 class Dog { constructor(name) { this.name = name; } } 狗应该能够做的不仅仅是有名字。它应该能够吠叫、摇尾巴和玩耍!我们可以创建一个 mixin 来为我们提供 bark 、 wagTail 和 play 属性,而不是直接将其添加到 Dog 中。 const dogFunctionality = { bark: () => console.log("Woof!"), wagTail: () => console.log("Wagging my tail!"), play: () => console.log("Playing!"), }; 我们可以使用 Object.assign 方法将 dogFunctionality mixin 添加到 Dog 原型中。此方法允许我们向目标对象添加属性:在本例中为 Dog.prototype 。 Dog 的每个新实例都可以访问 dogFunctionality 的属性,因为它们被添加到 Dog 的原型中。 class Dog { constructor(name) { this.name = name; } } const dogFunctionality = { bark: () => console....

August 4, 2023 · 2 min · 298 words · Anna.me