3

Is this allowed in javascript ?

a = {undefined : 1}
console.log(a[undefined])

[Edit] I think I was a bit messed up with habits of python, but I actually though about this one :

a = {[undefined] : 1}
console.log(a[undefined])
Note that it works for the reason is the same : undefined is casted as a string (like any value you pass with this synthax) and you end up defining the "undefined" prop

[/Edit]

And if so, does all browsers handle it the same and is it explicitly specified in the standards ?

[Edit]

NOTE : this question was slightly different from 'undefined' variable works as key to object with 'undefined' property name even though the fundamental reason and answer are the same. I asked in a context where undefined seems ambiguous as "is it the value undefined or the string "undefined" ? ", while the linked question state clearly "undefined" as a a prop name and asks about the name collision with keyword.

...And I think it can help other programmers used to Python or other language with json-like object/dict/hash synthax

[/Edit]

hl037_
  • 3,520
  • 1
  • 27
  • 58
  • 3
    there is almost certainly a better way to do this - what are you trying to achieve? – lucas Aug 27 '19 at 13:35
  • 1
    https://stackoverflow.com/a/17951523/6512438 maybe this helps you – kSp Aug 27 '19 at 13:36
  • 2
    This is allowed in JS. The undefined will be cast to the string "undefined" and used as the key. But you should never rely on this behaviour, so while allowed by the language, it's usually going to be a logical bug in your code. – Shilly Aug 27 '19 at 13:38
  • 1
    Same will happen for `null` – Vaibhav Vishal Aug 27 '19 at 13:39
  • @lucas I'm writing a function that takes an optional name to cache an object, when the name is not given, it should be stored in a kind of "default" key. knowing that undefined is allowed avoids having a test `if(name === undefined) { name = 'undefined'}` – hl037_ Aug 27 '19 at 13:41
  • If something is optional, I prefer it be a value, not a property. Then you can set that propertyto null or undefined instead. Makes it way easier to work with objects, especially in loops, since you do not have to check if a property exists all the time. So i would prefer `[{ "optional_name": "john" }, { "optional_name": undefined }]`, which completely removes the problem, since all objects should have the optional_name property. You can always cast it back easily by reducing Object.entries() to create a direct access hash. – Shilly Aug 27 '19 at 13:44
  • @kSp I saw it, and that gave me the idea to exploit it, but I wasn't sure it was legit – hl037_ Aug 27 '19 at 13:44
  • @Shilly this not the way I'd use it, I actually though about something like this : `const store = {}; export function getObj(name) { if(store[name] !== undefined) { return store[name] } else { return store[name] = { /*...*/ } }` ...In an internal module – hl037_ Aug 27 '19 at 13:48
  • 1
    In that case, I would use `return store[name] || { "some_default": true }`, so that you do not have to check for the string `"undefined"`. `store[name]` will be the value `undefined` anyway if the property does not exist. You could add a default value to `name` if you are afraid people will use `getObj()` and accidentally get whatever is behind the property string `"undefined"`, so that `name` will automatically become a valid string if none is passed into the function. – Shilly Aug 27 '19 at 13:53
  • So I would use `const store = { "placeholder": 1 }; function getObj( name = "placeholder" ) { return store[ name ]; }`. By using the default parameter of the function, using any falsy value for `name` will turn name into "placeholder" and hence, return whatever your store under that property name. – Shilly Aug 27 '19 at 13:59
  • Good point for the default value, forgot it was allowed in js nowadays. (but still requires special cares for IE) – hl037_ Aug 27 '19 at 14:04
  • Use the old school default value pattern `name = name || "placeholder"`, if old browsers are a problem. – Shilly Aug 27 '19 at 14:18

3 Answers3

8

Is this allowed in javascript ?

Yes.

And if so, does all browsers handle it the same

Yes.

is it explicitly specified in the standards ?

No.

It's just a consequence of undefined being converted to "undefined" when used in string context:

console.log( ("" + undefined).toUpperCase() )
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
4

Object property names are always strings. So whatever you pass as a property name gets converted to a string. If you pass undefined then it becomes "undefined". So this:

let obj = { undefined: 0 }
obj[undefined]

is the same as this

let obj = { undefined: 0 }
obj["undefined"]

undefined doesn't have a special meaning in that case. The same applies to null, false, true etc.

Szab
  • 1,263
  • 8
  • 18
  • 2
    "Object property names are always strings" — That used to be the case, but they can be Symbols too now. – Quentin Aug 27 '19 at 13:41
0

It Is allowed to access as Object property name

a = {undefined : 1}
console.log(a.undefined)
Pushprajsinh Chudasama
  • 7,772
  • 4
  • 20
  • 43