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?

tweekz
  • 237

2 Answers2

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.

JacquesB
  • 61,955
  • 21
  • 135
  • 189
-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.

Steve
  • 12,325
  • 2
  • 19
  • 35