访问导出变量的更改值

时间:2019-06-23 03:49:55

标签: javascript es6-modules

我有一个模块“ 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" ?
*/

2 个答案:

答案 0 :(得分:2)

  

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

不。导入变量时,将其副本复制到新变量中。如果原始变量得到了新的赋值,该副本将不会更改。

执行此操作时:

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

您正在将导出的默认值分配给名为test的新变量。该新变量不再与其他变量关联。

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

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

  2. 导出方法,该方法从模块内部检索变量的当前值。

  3. 创建一个事件,只要变量值更改,外部模块就可以监听并触发该事件。

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

答案 1 :(得分:1)

如已经说明的那样,默认导出无法观察到您期望的功能,但是不幸的是,命名导出会出现这种功能:< / p>

// 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答案中的方法。