【JS/Vue】export导出变量import引用时是“快照”还是“传址”?

8 阅读1分钟

这是一个很常见的 JavaScript/ES module 行为问题。

结论先行:

如果你用 export let foo = ... 方式导出变量,a/b 文件都 import 这个变量,a 文件修改后,b 文件用到的是“被修改后的值”,不是原始值。


详细解释

1. ES Module 的“live binding”特性

  • ES6 的模块导出(export let foo = ...)和导入(import { foo } from ...)是活绑定(live binding)
  • 这意味着:import 进来的变量是“引用”,不是“快照”

2. 举例说明

state.js

export let showPath = false;
export function setShowPath(val) { showPath = val; }

a.js

import { showPath, setShowPath } from './state.js';
setShowPath(true);
console.log('a.js', showPath); // true

b.js

import { showPath } from './state.js';
console.log('b.js', showPath); // 如果 a.js 已经 setShowPath(true),这里就是 true
  • 只要 a.js 先执行 setShowPath,b.js 里用到的 showPath 就是 true。

3. 注意事项

  • export default { showPath } 导出的是一个对象的引用,但对象的属性如果是基本类型(如 showPath = true),则是值的快照,如果是对象/数组,则是地址(引用)。
  • 如果你用 export const showPath = false;,则不能被其他模块修改(const 不能重新赋值)。

大坑再强调一遍

  • default导出:export default { showPath }
    • 基本类型是快照,引用类型是地址。
  • 具名导出:export { showPath }
    • 无论类型,import 的都是“活的绑定”,原始变量变了,import 的值也会变。