面试题答案
一键面试ES6模块系统工作原理
- 导入导出方式
- 导出:
- 命名导出:可以在声明变量、函数、类时直接导出,如
export const name = 'John';
或者在文件末尾统一导出const name = 'John'; export {name};
。 - 默认导出:一个模块只能有一个默认导出,使用
export default
关键字,如export default function() { console.log('This is a default export'); }
。
- 命名导出:可以在声明变量、函数、类时直接导出,如
- 导入:
- 导入命名导出:
import {name} from './module.js';
,可以通过as
关键字重命名,如import {name as newName} from './module.js';
。 - 导入默认导出:
import functionName from './module.js';
。 - 混合导入:
import functionName, {name} from './module.js';
。
- 导入命名导出:
- 导出:
- 处理循环依赖:ES6模块在处理循环依赖时,模块的导入是按引用进行的。当遇到循环依赖时,ES6模块会在解析阶段创建模块实例,并为其分配内存空间,即使模块尚未完全求值。这意味着在循环依赖链中的模块可以访问到彼此的导出,即使它们还没有完全执行完毕。例如,模块A导入模块B,模块B又导入模块A,模块A中的导入语句执行时,模块B已经在内存中有了一个“未完全初始化”的状态,模块A可以访问到模块B已导出的部分,避免了死循环。
- 与CommonJS模块的主要差异
- 加载方式:
- ES6模块:是静态加载,在编译阶段就确定模块的依赖关系,并且可以进行tree - shaking(摇树优化,去除未使用的代码)。
- CommonJS模块:是动态加载,在运行时才确定模块的依赖关系,这意味着CommonJS模块不能进行tree - shaking。
- 导出值的性质:
- ES6模块:导出的值是引用,对导出值的修改会反映到导入的模块中。
- CommonJS模块:导出的值是拷贝,对模块内部变量的修改不会影响导出的值。
- 模块执行时机:
- ES6模块:模块只在首次导入时执行一次,之后的导入都使用缓存。
- CommonJS模块:每次
require
都会执行模块代码,不过也有缓存机制,再次require
相同模块时会从缓存中读取结果。
- 加载方式: