导入是源模块环境中导出绑定的只读视图。即使源绑定是可变的(如您的示例中),您也不能使用它的导入视图来修改它。只有导出它的模块才能修改它。
为什么?因为一个导入变量的模块不应该能够进入源模块并改变变量的值。如果源模块想让模块使用它来更改导出变量的值,它可以公开一个函数来做到这一点。 (或者公开一个具有可变属性的对象。)
请记住,模块在导入它们的各个模块之间共享。因此,如果模块 A 和 B 都导入模块 C,您不希望模块 A 修改模块 B 看到的内容(即使模块 C 可以,因为它是变量,而不是常量)。
FWIW,这是一个例子 (live copy on plunker):
index.html:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<p id="display">0</p>
<script type="module" src="imp1.js"></script>
<script type="module" src="imp2.js"></script>
</body>
</html>
counter.js:
export let counter = 0;
export function increment() {
++counter;
}
imp1.js:
import { counter } from "./counter.js";
const display = document.getElementById("display");
setInterval(() => {
// This module sees changes counter.js makes to the counter
display.textContent = counter;
}, 100);
imp2.js:
import { counter, increment } from "./counter.js";
// Trying to set it directly fails
try {
counter = 127;
} catch (e) {
document.body.insertAdjacentHTML(
"beforeend",
"imp2: Failed to directly set counter to 127"
);
}
setInterval(() => {
// But it can ask counter.js to do it
increment();
}, 200);
我应该注意,虽然您不能修改绑定(在您的示例中为TimeZone),但如果您导出对象,则可以修改该对象的状态。例如:
// In the exporting module
export const container = {
TimeZone: 0,
};
// In the importing module
import { container } from "./module.js";
container.TimeZone = 42;
这行得通,并且任何同时导入container 的代码都可以看到更改。有时您想防御这种情况,您可以使用Object.freeze(如果源模块不需要更改对象的属性)或Proxy。
但同样,更改对象的状态与更改导出的绑定的值不同。