I've heard multiple explanations what the idea behind assignment in ECMAScript specification is. But which one does the EMCAScript spec actually apply? Let's take a look at a simple practical example:
Assignment by copying values, aka "the classic C++/Java approach".
let a = 4 // assign value 4 to variable a let b = a // copy value of a into b a = 5 // reassign a with value 5
Assignment by sharing a reference. Primitive values are immutable, Objects are mutable.
let a = 4 // Assigns a with a reference to the immutable value 4 let b = a // copies the reference of a to b a = 5 // reassigns a with a reference to 5 (in-place mutation would cause b to change as well)
Arguments for Variant 1:
Most importantly, ECMAScript itself seems to specify the assignment as copying values.
https://tc39.es/ecma262/#sec-declarative-environment-records-setmutablebinding-n-v-s
AssignmentExpression : LeftHandSideExpression = AssignmentExpression
1. If LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral, then
a. Let lref be ? Evaluation of LeftHandSideExpression.
b. If IsAnonymousFunctionDefinition(AssignmentExpression) and IsIdentifierRef of LeftHandSideExpression are both true, then
i. Let rval be ? NamedEvaluation of AssignmentExpression with argument lref.[[ReferencedName]].
c. Else,
i. Let rref be ? Evaluation of AssignmentExpression.
ii. Let rval be ? GetValue(rref).
d. Perform ? PutValue(lref, rval).
e. Return rval.
2. Let assignmentPattern be the AssignmentPattern that is covered by LeftHandSideExpression.
3. Let rref be ? Evaluation of AssignmentExpression.
4. Let rval be ? GetValue(rref).
5. Perform ? DestructuringAssignmentEvaluation of assignmentPattern with argument rval.
6. Return rval.
Branch 1d is particularly interesting for primitives, which ultimately leads to the SetMutableBinding method of the EnvironmentRecord, which states:
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.
Arguments for Variant 2:
On the other hand a lot of documentation suggests that example 1 might be the case. Like the explicit mentioning of immutability of primitive values, which only really makes sense if there would be a possibility to affect other variables by doing so (by having multiple references point to that value).
https://developer.mozilla.org/en-US/docs/Glossary/Primitive?retiredLocale=de
All primitives are immutable; that is, they cannot be altered. It is important not to confuse a primitive itself with a variable assigned a primitive value. The variable may be reassigned to a new value, but the existing value can not be changed in the ways that objects, arrays, and functions can be altered.
This explanation in Eloquent JavaScript I assume also talks about a reference (binding) pointing to a different value.
https://eloquentjavascript.net/04_data.html
Even though number values don’t change, you can use a let binding to keep track of a changing number by changing the value the binding points at.
My guess is, the specification is rather general. Which applies better to variant 1, but it is free to the implementor to implement it the way you want. Is that correct?