MST

星途 面试题库

面试题:JavaScript ES6模块系统的深度剖析

解释JavaScript ES6模块系统的工作原理,包括模块的导入导出方式,如何处理循环依赖,以及与CommonJS模块的主要差异。
15.4万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

ES6模块系统工作原理

  1. 导入导出方式
    • 导出
      • 命名导出:可以在声明变量、函数、类时直接导出,如 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';
  2. 处理循环依赖:ES6模块在处理循环依赖时,模块的导入是按引用进行的。当遇到循环依赖时,ES6模块会在解析阶段创建模块实例,并为其分配内存空间,即使模块尚未完全求值。这意味着在循环依赖链中的模块可以访问到彼此的导出,即使它们还没有完全执行完毕。例如,模块A导入模块B,模块B又导入模块A,模块A中的导入语句执行时,模块B已经在内存中有了一个“未完全初始化”的状态,模块A可以访问到模块B已导出的部分,避免了死循环。
  3. 与CommonJS模块的主要差异
    • 加载方式
      • ES6模块:是静态加载,在编译阶段就确定模块的依赖关系,并且可以进行tree - shaking(摇树优化,去除未使用的代码)。
      • CommonJS模块:是动态加载,在运行时才确定模块的依赖关系,这意味着CommonJS模块不能进行tree - shaking。
    • 导出值的性质
      • ES6模块:导出的值是引用,对导出值的修改会反映到导入的模块中。
      • CommonJS模块:导出的值是拷贝,对模块内部变量的修改不会影响导出的值。
    • 模块执行时机
      • ES6模块:模块只在首次导入时执行一次,之后的导入都使用缓存。
      • CommonJS模块:每次 require 都会执行模块代码,不过也有缓存机制,再次 require 相同模块时会从缓存中读取结果。