【问题标题】:Why is re-assigning imported objects throw ReferenceError?为什么重新分配导入的对象会抛出 ReferenceError?
【发布时间】:2019-03-23 21:23:08
【问题描述】:
// fileA.js

export let dataObj = {name: "intitial name"};

export let changeDataObj = () => {
 dataObj = Object.assign({}, {
      name: "changed in changeDataObj fn"
 });
}

//fileB.js
import {dataObj, changeDataObj} from "./fileA.js";

const myAsyncFunction = async () => {
   const response = await myApiCall();
   console.log(dataObj); // {name: "initial name"}
   console.log(response); // {name: "name from api"}
   dataObj = Object.assign({}, response); 
   // Throws ReferenceError: dataObj not defined on my computer with Webpack, babel
    // throws Error: "dataObj" is read-only. in codesandbox.io vanilla template using parcel. Codesandbox link https://codesandbox.io/s/nrn9o71jmm

   // but,
   changeDataObj();
   console.log(dataObj); // {name: "changed in changeDataObj fn"}
}

为什么我不能在myAsyncFunction 中重新分配dataObj,即使它在不同的文件中使用let 定义,但如果我调用与dataObj 在同一文件中定义的changeDataObj 则可以工作。这是预期的行为还是我错过了什么?

codesandbox.io 的链接https://codesandbox.io/s/nrn9o71jmm

请检查浏览器控制台而不是内置的代码和框控制台以查看错误。

【问题讨论】:

  • 这与async functions无关,但分配目标来自模块import

标签: javascript import es6-modules referenceerror


【解决方案1】:

为什么我不能在 myAsyncFunction 中重新分配 dataObj,即使它是用不同文件中的 let 定义的

答案在您收到的另一条错误消息中:

“dataObj”是只读的

所有导入都是只读的。如何定义它们并不重要。 ReferenceError 可能是由于代码的转换方式造成的。

但如果我调用与dataObj 在同一文件中定义的changeDataObj 则有效

因为dataObj 是该文件中的普通let 绑定。

【讨论】:

  • 感谢您的回答。是否是 Webpack 的事情抛出 ReferenceError: dataObj is not defined 而不是说 read-only 从 Parcel 看来是正确的。
【解决方案2】:

如果您只是想拥有一个名为 dataObj 的局部变量(这可能不是一个好的选择,但我会假设是这样),那么您需要一个 let 来表示您的声明:

let dataObj = Object.assign({}, response);

然后全局dataObj 被忽略,你得到一个新变量。不过,我认为这可能真的很令人困惑。

正如 Felix 所解释的,所有导入都标记为只读,因此无法分配新值。这实际上是一个很棒的功能。

【讨论】:

    猜你喜欢
    • 2019-07-23
    • 2017-05-17
    • 1970-01-01
    • 1970-01-01
    • 2014-07-31
    • 2019-11-27
    • 2016-09-18
    • 2023-03-03
    • 1970-01-01
    相关资源
    最近更新 更多