Search code examples
javascriptobjectpropertiesidentifieraccessor

Valid property names, property assignment and access in JavaScript


Updated Question

What, exactly, qualifies as a valid property name in Javascript? How do various methods of property assignment differ? And how does the property name affect property access?

Note

The answers to my original question (seen below) helped to clear some things up, but also opened a new can of worms. Now that I've had a chance to become a bit more familiar with JavaScript, I believe I've been able to figure a lot of it out.

Since I had a hard time finding this information consolidated into one explanation, I thought it might be helpful to expand my original question, and attempt to answer it.

Original Question

Originally, there was some confusion with the MDN JavaScript guide (object literals). Specifically, I wondered why they claimed that if a property name was not a valid JavaScript identifier, then it would have to be enclosed in quotes. Yet, they offered example code that showed that the number 7 could be used — without quotes — as a property name.

As it turns out, the guide simply left off one important part, and Pointy updated it (changes in bold):

If the property name would not be a valid JavaScript identifier or number, it must be enclosed in quotes.

I also wondered why property names were allowed to deviate away from the "may not start with a digit" rule, that applies to identifiers. That question actually reveals the complete misunderstanding that I had of property names, and is what lead me to do some more research.


Solution

  • Short Answer

    Object property names can be any valid identifier, numeric literal, or string literal (including the empty string).

    With that said, there are some potentially confusing intricacies to keep in mind about JavaScript property names, as described below.

    And unless you're working with valid (non-negative integer) array indexes, it's a good idea to explicitly assign all numerical property names as strings.

    Negative Numbers

    What might look like a negative number is actually an expression — something property names do not support.

    // SyntaxError
    const obj = { -12: 'nope' };
    

    Fortunately, bracket notation handles expressions for us.

    // Successful property assignment.
    const obj = {};
    obj[-12] = 'yup';
    

    Typecasting

    All property names are typecasted into strings before being stored.

    const obj = {
      12: '12'
    };
    
    console.log(typeof Object.keys(obj)[0]); // -> string
    

    Parsing

    But even before typecasting occurs, keys are parsed according to the syntax used, and transformed into a decimal literal.

    const obj = {
      // Valid string literal
      '022': '022',
    
      // Interpreted as decimal
      6: '6',
    
      // Interpreted as floating-point
      .345: '0.345',
    
      // Interpreted as floating-point
      1.000: '1',
    
      // Interpreted as floating-point
      8.9890: '8.989',
    
      // Interpreted as decimal
      000888: '888',
    
      // Interpreted as octal
      0777: '511',
    
      // Interpreted as hexadecimal
      0x00111: '273',
    
      // Interpreted as binary
      0b0011: '3',
    };
    
    
    /* Quoted property name */
    console.log(obj['022']); // "022"; as expected
    console.log(obj[022]); // undefined; 022 is an octal literal that evaluates to 18 before our lookup ever occurs
    
    /* Valid (non-negative integer) array index */
    console.log(obj[6]); // "6"; as expected
    console.log(obj['6']); // "6"; as expected
    
    /* Non-valid array index */
    console.log(obj[0x00111]); // "273"; we're accessing the property name as it was assigned (before it was parsed and typecasted)
    console.log(obj['0x00111']); // undefined; after parsing and typecasting, our property name seems to have disappeared
    console.log(obj['273']); // "273"; there it is, we found it using the evaluation of our original assignment