Skip to content

Instantly share code, notes, and snippets.

@shofel
Last active July 22, 2019 09:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shofel/f803b9c5efb64f47735bed8215d99080 to your computer and use it in GitHub Desktop.
Save shofel/f803b9c5efb64f47735bed8215d99080 to your computer and use it in GitHub Desktop.
blog

Preamble

These are pieces of valid js.

''[''] = ''['']

{}[{}] = {}[{}]

What do they really mean? Do they do anything?

Take a minute to reflet on the snippet... :)

Sense

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 ''

Conclusion

  1. 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.

  2. 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.

  3. Then we tasted controversial immutability of strings in js.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment