导入值与其导出值断开连接的状态仍然是只读的吗? [英] Are import values disconnected from their export values still read-only?

查看:88
本文介绍了导入值与其导出值断开连接的状态仍然是只读的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出以下模块结构:

// module A:
export let a = 1; // named export
export function inc() { a++; } // named export

// module B:
let b = 1;
export default b; // default export (equivalent to `export default 1`)
export function inc() { b++; } // named export

// module C:
let c = {};
export default c; // default export

// module E:
import a, {inc as incA} from "./A";
import b, {inc as incB} from "./B";
import c from "./C";

incA();
console.log(a); // logs 2, because "a" has a live connection to the export value
a++; // Error (because a is a live read-only view on the export)

incB();
console.log(b); // logs 1, because "b" is disconnected from the export value
b++; // Does this throw an error as well?

c.prop = true; // I think mutations are always allowed, right?
c = {}; // but are reassignment allowed too?

如果我默认导出表达式(export default bexport default 1),则相应的导入与该导出值断开连接.考虑到这一点,这样的导入是否仍是只读的,即可以重新分配ac吗?

If I have a default export of an expression (export default b or export default 1) a corresponding import is disconnected from this export value. Considering this, is such an import still read-only that is, can I reassign a or c?

推荐答案

导入绑定始终为只读,请参见摘要

Import bindings are always read-only, see the abstract CreateImportBinding operation in the spec, step 5:

  1. envRec 中为引用 M N2的 N 创建不可变间接绑定. em>作为其目标绑定,并记录绑定已初始化.
  1. Create an immutable indirect binding in envRec for N that references M and N2 as its target binding and record that the binding is initialized.

(我的重点)

ModuleDeclarationInstantiation 处理模块的导入条目.

That operation is used by ModuleDeclarationInstantiation when processing the import entries of the module.

所以:

b++; // Does this throw an error as well?

是的,b是只读的.

c.prop = true; // I think mutations are always allowed, right?

是提供的导出对象允许的.

Provided the exported object allows it, yes.

c = {}; // but are reassignment allowed too?

否,c是只读的.

在评论中,您说过:

但是当不再存在实时绑定时,将此类变量设置为只读是没有意义的

but when there isn't a live-binding anymore, it makes no sense to make such variables read-only

记住它们不是变量而是绑定是很有用的.尽管变量是绑定的一种,但并非所有绑定都是变量(即使在ES5和更早的版本中也是如此).

It's useful to remember that they aren't variables, they're bindings. While variables are one kind of binding, not all bindings are variables (even in ES5 and earlier).

关于它们无关紧要时是只读的,请记住涉及两层绑定:

Regarding them being read-only when it doesn't matter, remember that there are two layers of bindings involved:

  1. 源模块中 export 的实时绑定.
  2. 使用模块中 import 的实时绑定.
  1. The live binding of the export in the source module.
  2. The live binding of the import in the consuming module.

为了在#1的值不会改变时使#2可写,导入机制必须知道这一点,但是该信息不在

In order to make #2 writable when the value from #1 isn't going to change, the import mechanism would have to know that, but that information isn't in the module's exports. The exports just give the name of the exported binding.

此外,具有可变的导入绑定和不可变的导入绑定更难以理解,实现起来也更加复杂. (从样式的角度来看,重新分配导入的绑定也会造成混乱.)

Moreover, having mutable import bindings as well as immutable import bindings is more complicated to understand and more complicated to implement. (Reassigning imported bindings is also, from a style perspective, confusing.)

记住它们是实时绑定这一事实也很重要,这意味着导入的值可能会更改.假设:

It's also important to remember that the fact they're live bindings means the value of an import may change. Assume:

mod1.js:

export let foo = 41;
export function incrementFoo() {
    ++foo;
};

mod2.js:

import { foo, incrementFoo } from "./mod1.js";
console.log(foo); // 41
incrementFoo();
console.log(foo); // 42 <== it changed

在那种特殊情况下,是由mod2.js中的代码引起了更改(通过调用incrementFoo),但这不是必须的.可能是因为mod1.js中发生了一些与时间有关的事件以更改值,或者是其他模块调用mod1.js的结果,等等.

In that particular case, it was code in mod2.js that caused the change (by calling incrementFoo), but it doesn't have to be. It could be because some time-related event happened in mod1.js to make the value change, or the result of a call by some other module into mod1.js, etc.

但是,由于mod2.jsfoo是对mod1.jsfoo的实时绑定,因此mod2.js会看到更改.

But because mod2.js's foo is a live binding to mod1.js's foo, mod2.js sees the change.

这篇关于导入值与其导出值断开连接的状态仍然是只读的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆