5

From what I can tell, an import binding is immutable

import { foo } from './foo';
...
foo.bar = 23; // works 
...
foo = { bar: 23 }; // syntax error

However, I've read elsewhere that JS imports are actually non-writable (not immutable)...in which case wouldn't the first assignment statement, foo.bar = 23; also throw a syntax error?

UPDATE (how I understand it now)

...to paraphrase the excellent answer by @FelixKing...

JS imports are immutable bindings to the exported thing (variable, function, etc).

For non-primitive imports, this does not mean the properties on the imported object are necessarily immutable or non-writable.

Community
  • 1
  • 1
sfletche
  • 47,248
  • 30
  • 103
  • 119

1 Answers1

9

in which case wouldn't the first assignment statement, foo.bar = 23; also throw a syntax error?

Non-writable refers to the value of the variable, where as mutable (immutable) describes whether the value itself can be changed in place or not.

Imports are not writable as you have found out. But if the value of an import is mutable then you can update the value (in place).

foo.bar = 23;

does not assign a new value to foo. It is reading the value of foo and then modifying it (by adding or overwriting a property). If you did

var oldFoo = foo;
foo.bar = 23;
oldFoo === foo; // true

you would get true. That indicates that foo has still the same value assigned to it. It only updated the value (an object) in place.

All objects are mutable (unless passed to Object.freeze or similar functions), whereas primitive values (String, Number, etc) are all immutable.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • Thanks! So would it be correct to say that JS imports have an immutable binding, but imported objects themselves are mutable / non-writable? – sfletche Mar 29 '17 at 15:57
  • Yes, the import bindings are immutable but objects are mutable by default. – Felix Kling Mar 29 '17 at 15:58
  • Excellent! And non-writable implies that if `foo` already had a `bar` property defined (prior to import), then `foo.bar = 23` as shown above would also throw a syntax error. (This assignment statement only succeeds when `foo` does not already have a `bar` property.) Is that correct as well? – sfletche Mar 29 '17 at 16:03
  • That depends on how exactly the object was made "immutable". See [`Object.freeze`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) and [`Object.seal`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal). Individual properties can also be made non-writable via `Object.defineProperty`. I believe in all these cases, assigning to a non-writable property would simply silently fail (i.e. no error would be thrown). There certainly wouldn't be a *syntax* error because it is not known whether a property is... – Felix Kling Mar 29 '17 at 16:07
  • ... non-writeable until the code is actually executed. – Felix Kling Mar 29 '17 at 16:07
  • "Non-writable refers to the value of the variable, where as mutable (immutable) describes whether the value itself can be changed in place or not." <- I don't understand this differentiation whatsoever. You say it "Refers to the value of a variable", but the ability to change something in place is also "referring to the value of a variable", as in you can change the value of the variable in place or not. It seems to me that writable and mutable mean the exact same thing, even using your definition where you differentiate the two. (IMO, It seems like the differentiation is meaningless.) – ICW Oct 02 '19 at 18:22
  • @YungGun: Agreed, it doesn't sound as clear as I would like it to be. Non-writable means that you cannot assign a *new/different* value to the variable. Whereas "mutable" is a characteristic of the value itself (e.g. object values are mutable (by default), string values are not). – Felix Kling Oct 02 '19 at 20:48