Valid javascript object property names
Yes, objects can be used as maps, and any string can be a property name. As you've discovered, some properties can only be accessed using the bracket syntax.
window['abc']
is accessing a property. It is not a variable, even though it refers to the same value (at the global level) as:
abc
Valid property names, property assignment and access in JavaScript
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
Validating property names with regEx
Adding a negative lookahead should be good enough.
^(?![0-9])[a-zA-Z0-9$_]+$
Test
function validName(str) { // check if str meets the requirements return /^(?![0-9])[a-zA-Z0-9$_]+$/.test(str);}
console.log(validName("newName")) // should return TRUEconsole.log(validName("newName32")) // should return TRUEconsole.log(validName("_newName")) // should return TRUEconsole.log(validName("4newName")) // should return FALSEconsole.log(validName("new Name")) // should return FALSEconsole.log(validName("")) // should return FALSE
Property names in JavaScript
In JavaScript, property names are String values - any String values. That's just how the language is specified.
The relevant production:
PropertyName :
IdentifierName
StringLiteral
NumericLiteral
If an identifier, or a numeric literal is supplied, it is converted to a string value (SV).
See: http://ecma-international.org/ecma-262/5.1/#sec-11.1.5
So, for example:
var obj = {
foo: true, // the name of this property becomes 'foo'
'bar': true, // the name of this property becomes 'bar'
123: true // the name of this property becomes '123'
};
You can even use the empty string as a property name:
var obj = {
'': 'foo'
};
obj[''] // 'foo'
Can I skip the property names in an object declaration?
According to new ES6 shorthand syntax
return { isValid, credentials };
translates to
return { isValid: isValid, credentials:credentials };
which is valid
A question about JavaScript object property name
Have a look at the specification:
ObjectLiteral :
{ }
{ PropertyNameAndValueList }
{ PropertyNameAndValueList ,}
PropertyNameAndValueList :
PropertyAssignment
PropertyNameAndValueList , PropertyAssignment
PropertyAssignment :
PropertyName : AssignmentExpression
get PropertyName ( ){ FunctionBody }
set PropertyName ( PropertySetParameterList ){ FunctionBody }
PropertyName :
IdentifierName
StringLiteral
NumericLiteral
So a property name can be either an identifier name, a string or a number. 123
is a number whereas 123a
is neither of those above.
Object property name as number
You can reference the object's properties as you would an array and use either me[123]
or me["123"]
Related Topics
Capture Browser Console Logs with Capybara
Wkwebview - Complex Communication Between JavaScript & Native Code
Creating a "Sticky" Fixed-Position Item That Works on iOS Safari
How to Update Window.Location.Hash Without Jumping the Document
How to Execute Array of Promises in Sequential Order
Ios: Authentication Using Xmlhttprequest - Handling 401 Response
IE8 Var W= Window.Open() - "Message: Invalid Argument."
What Is the Fastest Factorial Function in JavaScript
How to Remove a Character from a String Using JavaScript
Using Enter Key with Action Button in R Shiny
Get Element at Specified Position - JavaScript
What Are "Top Level JSON Arrays" and Why Are They a Security Risk
Angular: Can't Find Promise, Map, Set and Iterator
Detect If Hovering Over Element with Jquery
Set a Request Header in JavaScript