访问导出变量的更改值

accessing changed value of exported variable

我有一个模块 "a",它导出一个初始化为 null 的变量。该变量被导入模块 "b".

对初始变量进行一些更改后,我尝试再次从模块 "b" 访问它,结果发现我得到了原始的 null 值。

这些变量不是作为参考导入的吗?意思是,它们应该反映在运行时稍后对它们所做的任何更改。

// main.js
import * as a from './a.js'
import * as b from './b.js'

// a.js
let test = null
export default test

export function change() {
  test = 'test'
  console.log(['in a.js change()', test])
}
console.log(['in a.js global', test])

// b.js
import test, { change } from './a.js'

console.log(['in b.js, pre a.change()', test])
change()
console.log(['in b.js, post a.change()', test])


/*
output:
Array [ "in a.js global", null ]
Array [ "in b.js, pre a.change()", null ]
Array [ "in a.js change()", "test" ]
Array [ "in b.js, post a.change()", null ]   WHY ISN'T THIS = "test" ?
*/

Aren't these variables being imported as reference? Meaning, they should reflect any changes made to them at a later point in runtime.

没有。当您导入变量时,您将其复制到一个新变量中。如果原始变量被分配了新的东西,该副本将不会改变。

当你这样做时:

import test, { change } from './a.js'

您正在将导出的默认值分配给名为 test 的新变量。那个新变量与另一个变量不再有任何联系。

有几种方法可以访问已更改的变量:

  1. 导出一个对象,其中变量是该对象上的 属性。 然后,在您的原始模块中,更改该 属性。在这种情况下,导入的模块将有一个指向同一对象的指针,因此当您访问该对象上的 属性 时,您将看到新值。

  2. 导出一个方法,从模块中检索变量的当前值。

  3. 创建一个外部模块可以监听的事件,并在变量值发生变化时触发该事件。

请记住,普通值是通过复制值并将其插入到新变量中来分配的。另一方面,通过复制指向同一对象的指针并将该指针放入新变量来分配对象。因此,对于对象,新变量包含指向同一对象的指针。

如前所述,default 导出无法观察到您期望的功能,但 named[=28 会出现=] 出口(不幸的是):

// a.js
export let test = null;

export function change() {
  test = "test";
  console.log(["in a.js change()", test]);
}
console.log(["in a.js global", test]);

// b.js

import { test, change } from "./a.js";

console.log(["in b.js, pre a.change()", test]);
change();
console.log(["in b.js, post a.change()", test]);

在这里,导入的test发生了变化,因为它是命名导入。

https://codesandbox.io/s/nice-liskov-se4fh

这种行为非常不直观,因为对于消费模块来说,它看起来有点像看起来是一个原始的神奇地重新分配自己,这看起来很疯狂任何其他Javascript 的上下文。这就是为什么通常建议永远不要重新分配导出的变量。使用不同的方法,例如 jfriend00 的回答中的方法。