返回

模块范围中的一个小小问题——ES6 模块范围引发思考

前端

引言

乍看之下,这个问题似乎微不足道:

有两个文件,fun.jsmain.js

// fun.js
const fun = () => {
  console.log('fun');
};
// main.js
import {fun} from './fun.js';
fun();

执行结果是什么?

答案显而易见。这不相当于直接在 main.js 中引入 fun.js 的内容吗?

ES6 模块范围

然而,在 ES6 模块中,情况并非如此。

在 ES6 中,模块具有自己的作用域。这意味着在模块中定义的变量和函数在模块外部不可见。

因此,在上面的示例中,fun 函数在 fun.js 模块中定义,但在 main.js 模块中不可用。

这与 CommonJS 模块不同,在 CommonJS 模块中,模块的导出直接成为全局变量。

一个真实的示例

以下是一个更真实的示例:

// utils.js
export const utilFunction = () => {
  console.log('utilFunction');
};
// main.js
import {utilFunction} from './utils.js';
utilFunction(); // Error: utilFunction is not defined

在此示例中,utilFunctionutils.js 模块中定义,但在 main.js 模块中不可用。因此,调用 utilFunction 会导致错误。

解决方案

要解决此问题,有两种方法:

  • utilFunction 导出为默认导出:
// utils.js
export default function utilFunction() {
  console.log('utilFunction');
}
// main.js
import utilFunction from './utils.js';
utilFunction(); // 输出: utilFunction
  • 使用 named export 并显式导入:
// utils.js
export const utilFunction = () => {
  console.log('utilFunction');
};
// main.js
import {utilFunction} from './utils.js';
utilFunction(); // 输出: utilFunction

结论

了解 ES6 模块的范围对于编写健壮且模块化的代码至关重要。通过注意模块边界,我们可以避免意外行为并确保代码的可维护性。