最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Are import values disconnected from their export values still read-only? - Stack Overflow

programmeradmin5浏览0评论

Given is the following module structure:

// 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?

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?

Given is the following module structure:

// 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?

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?

Share Improve this question asked Sep 2, 2016 at 9:50 user6445533user6445533 2
  • 1 Can't you just run the code and see the results? – jcubic Commented Sep 2, 2016 at 9:54
  • You can try to run the code with node --harmony – jcubic Commented Sep 2, 2016 at 14:46
Add a ment  | 

1 Answer 1

Reset to default 8

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

  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.

(my emphasis)

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

So:

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

Yes, b is read-only.

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

Provided the exported object allows it, yes.

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

No, c is read-only.


In a ment, you've said:

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

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. The live binding of the export in the source module.
  2. The live binding of the import in the consuming module.

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 plicated to understand and more plicated 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

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.

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

发布评论

评论列表(0)

  1. 暂无评论