Edit: I think my original answer was so wrong that it may not be redeemable at all, but since there's a great reply, I don't want to delete it outright. I will attempt to fix it.
I was trying to say that on the left side of an assignment there are only two choices for [ ]
, object access by key, and destructuring. Strings are objects without keys for each index in the text value. A destructuring expression doesn't fit either, and even then it would be a new expression (value) of undefined
, and thus not modify the original string. This may be why there is no error but it appears to do nothing. It modifies a (temporary) value of an expression that isn't stored anywhere.
Section 10.4.3.5 of the standard might be the closest thing to identifying the rule, saying the result is [[Writable]]: false
, but since it is still an expression, it represents a value that can still be assigned to something, even though that value will be discarded if not.
Interestingly, let B = 'abc'[1] = 'B'
would assign 'B' to B as expected, but not modify the string, regardless of whether it was a string constant or variable. And so let A='abc'; let B = A[1] = 'B'
has the same effect. So again, because it is a basic type without keys for [1]
in this case, the new expression is more of a new value than targeting the original memory where the string is stored.
Even more interesting: let B = undefined = 'B'
does successfully assign 'B' to B. I'm not quite sure how, but I think it's the same case as {}[1]
even though undefined
is an actual value that could have been assigned to B. I think this means there's an exception for an intermediate value in a sequence of assignments if it evaluates to undefined
, and does not pass on the undefined
to the next expression on the left.
I think it's the same case as undefined = 'B'
not doing anything, but that value on the left-hand side is still 'B'
, if assigned somewhere. I can predict that calling func(undefined = 3)
will in fact pass a 3 to the function.
Original answer: It was just so dead wrong that I've removed it now. Thanks to @hijarian for waking me up with his comment about the [ ]
operator.