[JS设计模式] Module Pattern

随着应用程序和代码库的增长,保持代码的可维护性和模块化变得越来越重要。模块模式允许将代码分成更小的、可重用的部分。

除了能够将代码分割成更小的可重用部分之外,模块还允许将文件中的某些值保留为私有。默认情况下,模块内的声明范围(封装)为该模块。如果我们不显式导出某个值,那么该值在该模块之外不可用。这降低了在代码库的其他部分声明的命名冲突的风险,因为这些值在全局作用域中不可用。

ES2015引入了内置的JavaScript模块。模块是一个包含JavaScript代码的文件,与普通脚本相比在行为上有一些不同。

让我们看一个名为math.js的模块示例,其中包含数学函数。

// 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;
}
// index.js
console.log(add(2, 3));
console.log(multiply(2));
console.log(subtract(2, 3));
console.log(square(2));

math.js 中定义了四个函数add,multiply,subtrack,square,我们想要在index.js中调用这几个函数。直接运行的话,会报错:Uncaught ReferenceError ReferenceError: add is not defined

[JS设计模式] Module Pattern_第1张图片

为了使index.js能调用到math.js中的函数,则需要先将这几个函数导出。使用关键词export将函数导出。

// math.js
export function add(x, y) {
  return x + y;
}
export function multiply(x) {
  return x * 2;
}
export function subtract(x, y) {
  return x - y;
}
export function square(x) {
  return x * x;
}

仅仅将math.js中的函数export还不够,还需要在index.js中,将需要调用的函数导入。

// index.js
import { add, multiply, subtract, square } from "./math.js";

接下来,我们在运行一下,看看效果:

直接运行报错了。在node.js环境下,按上述简单的代码构成是不够的。

解决方案

1. npm init -y
2. 在package.json中添加"type": "module",

我的代码结构如下:

[JS设计模式] Module Pattern_第2张图片

再次运行,结果如下:

[JS设计模式] Module Pattern_第3张图片

可以看到,math.js中的4个显示声明的函数可以导出,index.js中也能正常导入这四个函数,并正常调用。

接下来,我们尝试下,如果在math.js中的变量不声明为export,看index.js是否还可以调用。

[JS设计模式] Module Pattern_第4张图片

显然和我们预想的一致,不会奏效。

通过将值保留为模块私有,可以降低意外污染全局作用域的风险。不必担心模块使用者会意外覆盖模块内部的变量的值,这些变量可能与模块的私有变量具有相同的名称:它可以防止命名冲突

如果从模块导出的命名和当前文件的本地命名有冲突,怎么解决呢?

[JS设计模式] Module Pattern_第5张图片

可以通过as关键字重命名被导入的函数名。

[JS设计模式] Module Pattern_第6张图片

上述代码将addmultipy重命名为addValuesmultiplyValues。消除了命名冲突问题。

除了有我们上述代码中使用的命名导出外,还有默认导出

[JS设计模式] Module Pattern_第7张图片

在math.js中将add函数声明为export default,可以在index.js中直接调用。如果默认导出的函数有命名冲突的话,可以直接在index.js中重命名

[JS设计模式] Module Pattern_第8张图片

[JS设计模式] Module Pattern_第9张图片

你可能感兴趣的:(JavaScript设计模式,javascript,设计模式,开发语言)