These are pieces of valid js.
''[''] = ''['']
{}[{}] = {}[{}]
What do they really mean? Do they do anything?
Take a minute to reflet on the snippet... :)
When you read them strictly from left to right, it doesn't make much sense: get the value of the element with index ''
of the object ''
and then assign another value to it.
By design, lhs (left-hand side) of the assignment operator is not a value, but a symbolic representation of the place where the runtime should put the rhs (right-hand side), which is a value.
That means even if rhs and lhs look the same, their meaning is completely different:
''[''] = ''['']
({})[{}] = ({})[{}]
Lhs is always a place, and rhs is always a value.
There are simpler cases when rhs is a completely symbolic representation of a place: x = 3
. Here x
is a symbol and 3
is a value. But in ''[''] = 0
lhs consists of ''
and ['']
, the second part is, again, just symbolic; but the first must be evaluated to find the place by accessing with ['']
. Let's compare with x[''] = 0
; it appears to be completely different notation! Or not... At first sight the difference is that ''
is already a value, but x
is not yet. But really, they could be handled the same way: both ''
and x
are evaluated before getting the place. That's because in js values of objects are not real values, but places: {} !== {}
. (I could be wrong here, but it looks as a handful adhoc model.)
> x = {}
> x[''] = ''
> x
{"": ""}
Ok, good. x
is a place we can write to it and then read from it.
> {}[''] = ''
> {}
{}
The place we write to and the place we read from are not the same: {} !== {}
.
Given all this, the strings look really interesting: we could reference the same value (and the same place) without having a var for it: '' === ''
.
Even though the very ''
is not a valid lhs for assignment, a place given by index in it appears to be a valid lhs:
> ''[0] = '1'
> ''[0]
undefined
Hm.. We know properly well that '' === ''
. This obviously is the same place. Ok, let's narrow this down.
> x = 'y'
> x[0] = 'x'
> x[0]
"y"
Wha? Now there is no any doubt that we write and read the same place. Then what the f?
...LOL ahah! The strings are immutable in js :D https://stackoverflow.com/a/1431113/1991011.
The things are even cooler than that. Strings are proper objects, and one can lookup a property on it: 'x'.length
; it also makes a string a valid part of lhs for assignment operator. But no one can write anything to a string object:
> x = ''
> x.y = 'y'
> x.y
undefined
By the way, we can achieve this behaviour with any object. Just use Object.seal
(http://mdn.io/object.seal).
Most disappointing part of this is silent fail: no errors, no messages. You can get them in strict mode
:
> (() => { 'use strict'; ''[''] = '' })()
Uncaught TypeError: Cannot create property '' on string ''
-
Starting with a fresh look to lhs of assignment operator, we notice that
[]
has got different meaning in it: not getting a value, but getting a place. -
To notice side-effect of assignment we must first create a variable, to reach the same place and to check it after altering. But with strings we can reference the same value (and place?) without creating a var. It looks like a great idea but it doesn't work it practice.
-
Then we tasted controversial immutability of strings in js.