A key is a runtime value whereas an identifier is a syntactical element.
Objects in JS do not have a fixed shape, you can create, update and delete properties in them at will. And you can do so dynamically, without knowing the names of the properties when you write the program, using bracket notation: obj[prop] = val
. And similarly you can loop over the keys of an object with for (const prop in obj)
. This is why keys are strings (or symbols) - you need to access them with/as string values.
The term "identifier" refers to specific syntax in the grammar of the language. It is written by the programmer and parsed by the compiler. Notice that in the expression obj.prop
, both "obj
" and "prop
" are identifiers, so they don't even have to refer to variables. They are just the subset of strings you can write to name variables and properties with dot syntax. They are not values you can access from a javascript program, and don't really exist at runtime any longer.
You might have meant variables though. Variables are distinguished by identifiers, the same identifier in the same scope will refer to the same variable. This distinction happens by name, treating the variable names as strings in the compiler. You just never get in contact with those strings from JS code. When the code is executed, for each declared name a variable with a value will be created in an environment structure for that scope.
So there is some similarity:
- An object consists of property keys associated with property values.
- A scope environment consists of variable names associated with variable values.
And actually, this similarity is (or has been) exploited by usage of eval
and with
statements and the global object, that actually allow the dynamic creation and assignment of variables by name. For these, the interpreter has to keep the variable names (as strings) in memory. It's inefficient and despised though. When they (both object keys and variable names) are not dynamic, the interpreter will be able to optimise them a lot.