0%

JavaScript 模块化 Export 与 Import

JavaScript模块化是一种将代码分解为独立功能的策略,每个模块都专注于一个特定的任务或功能。这样可以提高代码的可维护性、可测试性和复用性。

在ES6之前,JavaScript没有官方的模块系统,开发者只能通过全局变量、立即执行的函数表达式等方法实现代码模块化。ES6带来了官方的模块导入和导出语法,使得模块化编程更加简单和直观。

导出(Export)

在JavaScript中,你可以选择单个导出或者批量导出模块的内容。下面将具体介绍这两种方式:

单个导出

单个导出是指在代码的各个部分使用 export 关键字来导出某一部分。例如,你可以导出一个变量、一个函数或一个类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// myModule.js
export const name = 'John Doe';

export function sayHello() {
console.log(`Hello, ${name}!`);
}

export class Person {
constructor(name) {
this.name = name;
}

greet() {
console.log(`Hello, ${this.name}!`);
}
}

批量导出

批量导出则是在模块的末尾,一次性导出多个部分。你需要将要导出的部分放在大括号 {} 中,并用逗号 , 分隔。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// myModule.js
const name = 'John Doe';

function sayHello() {
console.log(`Hello, ${name}!`);
}

class Person {
constructor(name) {
this.name = name;
}

greet() {
console.log(`Hello, ${this.name}!`);
}
}

export { name, sayHello, Person };

在上述例子中,我们先定义了三个元素,然后在最后一行使用一个 export 语句进行了批量导出。

无论你使用哪种导出方式,其他模块都可以使用 import 关键字来导入它们:

1
2
3
4
5
6
7
8
// anotherModule.js
import { name, sayHello, Person } from './myModule.js';

console.log(name); // logs: "John Doe"
sayHello(); // logs: "Hello, John Doe!"

const john = new Person('John');
john.greet(); // logs: "Hello, John!"

注意:在使用 import 导入内容时,必须确保导入的名称与导出的名称完全匹配。

默认导出(Default Export)

默认导出是模块化系统中的一个特性,每个模块可以有一个默认导出。使用 export default 可以定义默认导出。

默认导出在一个模块中只能有一个。它是模块的主要导出,可以是一个函数,一个类,一个对象或任何其他值。

默认导出通常用于以下场景:

  • 当模块只导出一个特定的值时(例如,一个函数或者一个类),这时候使用默认导出是最合适的。
  • 当你希望该模块的主要功能易于导入时。

通过export default语句来定义一个模块的默认导出:

1
2
3
4
// greeter.js
export default function(name) {
console.log(`Hello, ${name}!`);
}

然后你可以在其他模块中用如下方式导入默认导出的部分:

1
2
3
4
// app.js
import greet from './greeter.js';

greet('John Doe'); // logs: "Hello, John Doe!"

注意,在导入默认导出时,你可以给它任意名称。因为默认导出在其模块内只有一个,所以无需担心命名冲突。

同时,一个模块还可以包含一个默认导出和多个具名导出:

1
2
3
4
5
6
7
8
// myModule.js
const name = 'John Doe';
function sayHello() {
console.log(`Hello, ${name}!`);
}

export { sayHello }; // named export
export default name; // default export

在这种情况下,你可以这样导入:

1
2
3
4
5
// anotherModule.js
import defaultName, { sayHello } from './myModule.js';

console.log(defaultName); // logs: "John Doe"
sayHello(); // logs: "Hello, John Doe!"

在此示例中,defaultName是默认导出的值(可以自定义命名),而sayHello是具名导出的函数。

导入(Import)

在JavaScript中,你可以使用 import 关键字来导入模块的内容。具体来说,你可以选择单个引入或批量引入。

单个引入

单个引入是指从模块中只导入一个特定的部分。例如,你可以从一个模块中只导入一个变量、一个函数或一个类:

1
2
3
4
// anotherModule.js
import { name } from './myModule.js';

console.log(name); // 如果myModule.js中导出了一个名为"name"的变量,会打印该变量的值

在这个例子中,我们只从 ‘myModule.js’ 模块中导入了一个名为 ‘name’ 的变量。

批量引入

批量引入则是同时从一个模块中导入多个部分。你需要将要导入的部分放在大括号 {} 中,并用逗号 , 分隔。

1
2
3
4
5
6
7
8
// anotherModule.js
import { name, sayHello, Person } from './myModule.js';

console.log(name); // 如果myModule.js中导出了一个名为"name"的变量,会打印该变量的值
sayHello(); // 如果myModule.js中导出了一个名为"sayHello"的函数,会执行此函数

const john = new Person('John'); // 如果myModule.js中导出了一个名为"Person"的类,创建这个类的实例
john.greet(); // 调用实例方法

在上述例子中,我们从 ‘myModule.js’ 模块中导入了三个部分:一个名为 ‘name’ 的变量,一个名为 ‘sayHello’ 的函数,和一个名为 ‘Person’ 的类。

引入全部

你也可以一次性导入模块中导出的所有内容:

1
2
3
4
5
6
7
8
// anotherModule.js
import * as MyModule from './myModule.js';

console.log(MyModule.name);
MyModule.sayHello();

const john = new MyModule.Person('John');
john.greet();

在这个例子中,我们使用 * 符号和 as 关键字将 ‘myModule.js’ 中导出的所有内容都导入到一个名为 ‘MyModule’ 的对象中。然后,我们就可以通过这个对象来访问这些内容。

注意:无论你选择哪种引入方式,在使用 import 引入内容时,必须确保导入的名称与导出的名称完全匹配(除非你使用默认导出,那么可以自定义名称)。

大括号的用法

在JavaScript模块化中,import语法的使用取决于对应模块的导出方式:

  1. **具名导出(Named exports)**:如果一个模块使用了具名导出(export),那么在导入时,你需要使用大括号 {} 把要导入的内容包括起来,并且名称必须与模块中导出的名称一致。例如:

    1
    2
    3
    4
    5
    6
    // myModule.js
    export const name = 'John Doe';

    // anotherModule.js
    import { name } from './myModule.js';
    console.log(name); // John Doe
  2. **默认导出(Default export)**:如果一个模块使用了默认导出(export default),那么在导入时,你可以不使用大括号,而且可以给导入的内容自定义名称。例如:

    1
    2
    3
    4
    5
    6
    // myModule.js
    export default 'John Doe';

    // anotherModule.js
    import name from './myModule.js'; // 可以自定义名称
    console.log(name); // John Doe

因此,如果是从具名导出中导入单个项,那么必须使用大括号{}。如果是从默认导出中导入,那么不需要使用大括号{}