代码之家  ›  专栏  ›  技术社区  ›  Old Geezer

导出的变量是只读的吗?

  •  2
  • Old Geezer  · 技术社区  · 7 年前

    globals.ts:

    export let TimeZone: number = 0;
    

    import * as globals from "./globals";
    globals.TimeZone = -5;
    

    最后一行给出:

    错误TS2540:无法分配给“时区”,因为它是只读属性。

    1 回复  |  直到 7 年前
        1
  •  15
  •   T.J. Crowder    7 年前

    进口是一个巨大的挑战 只读视图 源模块环境中导出的绑定的。即使源绑定是可变的(如示例中所示),也不能使用它的导入视图来修改它。只有导出它的模块才能修改它。

    为什么?因为导入变量的一个模块不应该能够进入源模块并更改变量的值。如果源模块希望使用它的模块能够更改导出变量的值,那么它可以公开一个函数来执行此操作。(或公开具有可变属性的对象。)

    请记住,模块是 共享 跨各个模块导入它们。因此,如果模块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);
    
    推荐文章