globals.ts:
export let TimeZone: number = 0;
app.js
import * as globals from "./globals";
globals.TimeZone = -5;
最后一行给出:
错误TS2540:因为它是一个只读属性,所以无法分配给“ TimeZone”。
为什么?
答案 0 :(得分:5)
导入是源模块环境中导出的绑定的只读视图。即使源绑定是可变的(如您的示例中所示),也不能使用导入的视图对其进行修改。只有导出它的模块可以修改它。
为什么?因为导入变量的一个模块不应该到达源模块并更改变量的值。如果源模块希望使使用它的模块能够更改导出变量的值,则可以公开一个函数来执行此操作。 (或公开具有可变属性的对象。)
请记住,模块在导入模块的各个模块之间共享。因此,如果模块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);