Skip to content

模块化

题目1: ES6 中如何使用 importexport 实现模块化?

答案: 导出(export):

javascript
// math.js
export const PI = 3.14159;
export function square(x) {
    return x * x;
}

导入(import):

javascript
// main.js
import { PI, square } from './math.js';
console.log(PI); // 3.14159
console.log(square(2)); // 4

扩展: 还可以使用 export default 进行默认导出,使用 import * as 导入所有导出项。

题目2: 与 CommonJS 模块系统的区别?

答案: 主要区别:

  1. 语法:ES6 使用 importexport,CommonJS 使用 requiremodule.exports
  2. 加载时机:ES6 模块是静态的,在编译时就确定依赖关系;CommonJS 是动态的,在运行时加载
  3. 导出值:ES6 模块输出的是值的引用,CommonJS 模块输出的是值的拷贝
  4. 同步/异步:CommonJS 是同步加载,ES6 模块可以异步加载

扩展: ES6 模块在浏览器中需要使用 <script type="module"> 标签。

题目3: 如何实现动态导入?

答案: 使用 import() 函数可以实现动态导入:

javascript
if (condition) {
    import('./module.js')
        .then(module => {
            module.function();
        })
        .catch(error => {
            console.error('Module loading failed');
        });
}

扩展: 动态导入返回一个 Promise,可以与 async/await 一起使用。

题目4: 什么是命名导出和默认导出?它们有什么区别?

答案: 命名导出:

javascript
export const name = 'John';
export function sayHello() { /* ... */ }

默认导出:

javascript
export default function() { /* ... */ }

区别:

  1. 一个模块可以有多个命名导出,但只能有一个默认导出
  2. 导入时,默认导出可以使用任意名称,而命名导出必须使用原始名称(或通过 as 重命名)

扩展: 可以在同一个模块中同时使用命名导出和默认导出。

题目5: 如何处理循环依赖?

答案: 循环依赖是指两个或多个模块相互依赖。ES6 模块可以处理循环依赖,但需要谨慎设计:

  1. 将循环依赖的部分提取到单独的模块
  2. 使用动态导入
  3. 重构代码以消除循环依赖

示例:

javascript
// a.js
import { b } from './b.js';
export const a = 1;
console.log(b);

// b.js
import { a } from './a.js';
export const b = 2;
console.log(a);

扩展: 虽然 ES6 模块可以处理循环依赖,但过多的循环依赖可能表明代码结构需要改进。