3

Why does the following code work?

var x = []
x[function() {}] = "Hi"

/* prints "Hi" */
console.log(x[function() {}])

Edit

I know that everything get's converted to a string-property, but why can I add x["function() {}"] = "Yo" then and have both properties?

enter image description here

Fabian Zeindl
  • 5,860
  • 8
  • 54
  • 78
  • 3
    `console.log(x)` could explain why it works. – robertklep May 18 '16 at 08:27
  • 3
    Why wouldn't you expect it to work? – Bergi May 18 '16 at 08:28
  • 4
    anything between [ ] is evaluated and converted to string. and that converted string acts as the key of the object. so function() {} is converted to "function () {}". Later u access that key from the object. – Avinash May 18 '16 at 08:29
  • "*why can I add `x["function() {}"] = "Yo"` then and have both properties?*" - you cannot. It's the same property. – Bergi May 18 '16 at 09:28
  • 2
    Looking at your screenshot, apparently the function is serialised with a space between the `function` keyword and the parameter list, so it's two different strings. – Bergi May 18 '16 at 09:33
  • Should I delete this question? – Fabian Zeindl Jun 27 '16 at 07:34

2 Answers2

8

In my understanding, when you put anything in [], that value is converted to string.

So when you do [function(){}], it means ["function(){}"] which is a valid value.

If you try something like this, it would be more evident:

var foo = {};
var bar = {};

var a = [];
a[foo] = "hello";
a[bar] = "world";

console.log(a[foo], a[bar], Object.keys(a))
Rajesh
  • 24,354
  • 5
  • 48
  • 79
1

The property names of objects (including arrays) are always strings in JavaScript. If the value passed to indexer is not a string, it's coerced to such. (function (){}).toString() === (function() {}).toString()

noppa
  • 3,947
  • 21
  • 22