1

I am trying to wrap my head around what the ECMAScript specification suggests about variable assignment.

Introduction:

Coming from Java, this is pretty straight forward. Variables get stored at a memory location and assigning one variable to another one copies the value of the first into the memory location of the second.

int a = 4; // 0x0001: 4
int b = a; // 0x0002: 4

In the case of reference types, this works the same, only that the value being copied is a reference.

Object a = new Object(); // 0x0001: 0x0010 => 0x0010: Object
Object b = a; // 0x0002: 0x0010 => 0x0010: Object

So, after spending some time reading through the ECMAScript specification, I still can't quite put my finger on what mental model it wants us to apply for Javascript. I am aware, that the specification does not make any implications about a memory model - but it still got to use some kind of mental variable-model.

Problem:

In the specification, there are Declarative Environment Records, which provide bindings between names and values. https://tc39.es/ecma262/#sec-declarative-environment-records-setmutablebinding-n-v-s

It attempts to change the bound value of the current binding of the identifier whose name is N to the value V.

V is an ECMAScript laguage type. This is exclusively one of the following: Undefined, Null, Boolean, String, Symbol, Number, BigInt, and Object

But as we all know

let a = { a: 4 }
let b = a

will not copy the value of a to b, but rather reference the same object. However, the specification explicitly speaks of ECMAScript language types as bound values - not references.

You might say, the variable is bound to the ECMAScript language value via the reference. But this would be implementation detail and thus the spec does not explain the difference between objects and primitives in a consequent manner.

Furthermore MDN states that primitives only differ from objects by their immutability. If primitives would get copied from one place to the other, this would not even be worth mentioning - it's a given.

So my current guess is:

In JS, variables always point to values. When copying variables, you always point to those respective values - so it's rather like setting a reference to values than values being physically copied. In that sense, the MDN explanation makes perfect sense that primitives differ by their immutability. Plus, it aligns with the greater part of the implementation in V8 (except for SMIs).

Is this correct, or am I overseeing something?

2 Answers 2

4

Your understanding is correct, but the explanation gets confusing because you are mixing terminology from lower-level languages like Java with the terminology from ECMAScript specification, which operate on higher level. In particular, the meaning of "value" gets ambiguous.

The conceptual model used in the ECMAScript specification is that variables are bindings between names and values. An assignment binds a name to a new value. Multiple names can be bound to the same value. Objects are a kind of value, so are strings and numbers. Some values are immutable, some are mutable.

This is all you need to know. This model does not talk about memory locations, references, reference types, copying etc. since these are implementation details.

When you say "the value being copied is a reference", you are using terminology from Java, where "value" refers to the reference, not to the object it references. But when ECMAScript talks about "value" it refers to the object itself.

JavaScript can be implemented similarly to Java - where a binding is a variable memory location, and where assignment a = b happens by copying a reference from the a variable to the b variable.

16
  • "This model does not talk about memory locations, references" – And neither does Java, BTW. The OP's assertion that in Java, variables get stored at memory locations is just plain wrong. There is nothing anywhere in the JLS that talks about memory locations. It would be perfectly legal for a standards-conformant Java implementation to print the values out on paper and not store them in memory at all, or change the memory locations of variables at runtime, or do whatever else it wants. Commented May 28, 2023 at 15:56
  • 1
    @JörgWMittag, even if things were printed, there would still have to be a scheme to organise these printouts and their contents, and allow automatic access to them, akin to "memory" as we know it. There's all kinds of weird card tricks that could be performed behind the scenes, but the effect would still have to be the same as if none of those tricks were occurring and we were dealing with our usual conceptual models about how objects work. If it didn't, people would just declare the written standard to be non-conformant or under-specified.
    – Steve
    Commented May 28, 2023 at 19:13
  • 1
    @JörgWMittag: The Java Virtual Machine Specification talks about memory locations, stack, heap, references etc.
    – JacquesB
    Commented May 28, 2023 at 19:32
  • @JacquesB, is there an example of a JavaScript implementation where variable names are not aliases for storage addresses, and more importantly, where the behaviour of the program is inconsistent with a conceptualisation in which variables are aliases for storage addresses? It would seem contrary to the tenets of programming as we know it.
    – Steve
    Commented May 29, 2023 at 8:53
  • 1
    @JörgWMittag While you could implement a JVM like that, I think it still violates the spec, as it is indeed very precise about certain things like references.
    – tweekz
    Commented May 29, 2023 at 9:40
-2

It sounds like the writer of the standard suffered from a conceptual muddle.

Mathematicians do things like "bind names to values" - or, if I understand their practices correctly, it's more accurate to say they bind values to symbols.

Computer scientists bind names to storage addresses - or to put it another way, storage addresses are aliased with names.

This "binding" is not the same process in each context, the counterpart to which a "name" is bound in each context is not the same, and (with all respect to @JacquesB's answer, with which I disagree) there is no equivalence between these concepts nor common hierarchy in which they exist at different levels.

14
  • Hi Steve, I have a long journey of adapting to this more general view - but it makes sense. The model that JS applies does not make any assumptions about actual memory. So it is up to the implementor.
    – tweekz
    Commented May 29, 2023 at 9:25
  • @tweekz, it may not say it makes any assumptions, and it may even say it doesn't make assumptions, but I'll bet you it does make assumptions!
    – Steve
    Commented May 29, 2023 at 9:50
  • @Steve: There is no conceptual muddle in the ECMAScript standard - all concepts are unambiguously defined. Just don't mix concepts from different domains or different standards.
    – JacquesB
    Commented May 29, 2023 at 9:59
  • 1
    @Steve You have a point distinguishing mathematicians from implementers of computer systems, but the language designers can use the mathematical terms, and in doing so give freedom to have different implementations.
    – Caleth
    Commented Jun 1, 2023 at 8:49
  • 1
    It's precisely because we only require the abstract "binding names to values" that we can have implementations which do optimisations that break the conception "a variable is a storage location"
    – Caleth
    Commented Jun 1, 2023 at 10:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.