Object property name as number

JavascriptObject

Javascript Problem Overview


According to the official JavaScript documentation you can define object literal property names using integers:

> Additionally, you can use a numeric or string literal for the name of a property.

Like so:

me = {
	name: "Robert Rocha",
	123: 26,
	origin: "Mexico"
}

My question is, how do you reference the property that has an integer as a name? I tried the usual me.123 but got an error. The only workaround that I can think of is using a for-in loop. Any suggestions?

Javascript Solutions


Solution 1 - Javascript

You can reference the object's properties as you would an array and use either me[123] or me["123"]

Solution 2 - Javascript

Dot notation only works with property names that are valid identifiers. An identifier must start with a letter, $, _ or unicode escape sequence. For all other property names, you must use bracket notation.

In an object literal, the property name must be an identifier name, string literal or numeric literal (which will be converted to a string since property names must be strings):

var obj = {1:1, foo:'foo', '+=+':'+=+'};

alert(obj[1] + ' ' + obj.foo + ' ' + obj['+=+']); // 1 foo +=+

Solution 3 - Javascript

You can use me[123] or me["123"]. Both work.

Solution 4 - Javascript

You can use bracket notation me[123].

Solution 5 - Javascript

Just in case anyone else was confused by this: using integer (rather than string) property names may give slightly different - though functionally the same - results (depending on the browser) when you have objects within objects.

Simple objects with no nested objects have consistent behavior across browsers (though as the accepted answer says, we need to use brackets instead of dots to access integer property names):

var str_simple = {
	a: "b", c: "d", e: "f", g: "h",
};
str_simple.a === "b"; // true
str_simple.e === "f"; // true

var int_simple = {
	1: 2, 3: 4, 5: 6, 7: 8,
};
int_simple[1] === 2; // true - must use brackets instead of dots
int_simple[5] === 6; // true
// this works b/c int property names are coerced to strings anyway
int_simple[1] === int_simple['1']; // true

And this nested object with string keys works exactly as expected:

var str_nested = {
    a: {b: "c"}, 
    d: {e: "f", g: "h"},
};
str_nested.a; // returns object as expected, no matter the browser - {b: "c"}
str_nested.a.b === "c"; // true
str_nested.d.g === "h"; // true

But this equivalent nested object with integer keys returns slightly different results depending on the browser, though you can still access the nested objects in the same way (so functionally, it still works the same):

var int_nested = {
	1: {2: 3}, 
	4: {5: 6, 7: 8},
};

// latest Chrome (57)
// Safari 10 (latest for my Mac, 10.10 Yosemite)
int_nested[1]; // returns object as expected - {2: 3}
int_nested[1][2] === 3; // true

// latest Firefox (52)
int_nested[1]; // RETURNS ARRAY-LIKE OBJECT - Object [ <2 empty slots>, 3 ]
int_nested.length; // undefined because it's not technically an array
int_nested[1][2] === 3; // true - works b/c object was padded with empty slots

// and again, in all browsers, we can exchange the integer keys
// for equivalent strings since property names are coerced to strings anyway
int_nested[1][2] === int_nested['1'][2];
int_nested['1'][2] === int_nested[1]['2'];
int_nested[1]['2'] === int_nested['1']['2'];

This behavior will still be slightly different but functionally the same if you programmatically construct a nested object. For example, say we wanted to write a function that would take a list of pairs (e.g. [[0, 0], [0, 1], [1, 2], [2, 3]]) and convert it into a nested object so we could check if the pair is in the object with O(1) time (e.g. {0: {0: true, 1: true}, 1: {2: true}, 2: {3, true}}). Note that Sets check reference equality and not value equality, so we couldn't store the pair itself in the Set and achieve the same results:

// [[0, 0], [0, 1], [1, 2], [2, 3]] ->
// {
// 	0: {0: true, 1: true},
// 	1: {2: true},
// 	2: {3: true},
// }
function createNestedObject(pairs) {
	var obj = {};
	for (var pair of pairs) {
		var x = pair[0], y = pair[1];
		// must create outer object for each unique x or else
		// obj[x][y] would fail b/c obj[x] would be undefined
		if (!obj.hasOwnProperty(x)) {
			obj[x] = {};
		}
		obj[x][y] = true;
	}
	return obj;
}

function exists(nested, pair) {
    var x = pair[0], y = pair[1];
    // uses !! operator so if pair isn't in nested
    // we return false instead of undefined
    return !!(nested[x] && nested[x][y]);
}

Pairs with strings will work as expected:

var pairs = [["a", "a"], ["a", "b"], ["c", "d"], ["d", "e"]];
var nested = createNestedObject(pairs);
nested; // as expected - {a: {a: true, b: true}, c: {d: true}, d: {e: true}}
exists(nested, ["a", "a"]); // true
exists(nested, ["a", "b"]); // true
exists(nested, ["ZZZ", "ZZZ"]); // false

But in certain browsers, integer pairs will be different but functionally the same:

var pairs = [[0, 0], [0, 1], [1, 2], [2, 3]];
var nested = createNestedObject(pairs);
nested; // in Safari 10/Chrome 57 - returns nested objects as expected
nested; // in Firefox 52 - Object [ Object[2], Object[3], Object[4] ]
// BUT still gives correct results no matter the browser
exists(nested, [0, 0]); // true
exists(nested, [0, 1]); // true
exists(nested, ['0', '0']); // true
exists(nested, [999, 999]); // false

Solution 6 - Javascript

The situation with numeric property names seems more complicated than it is explained in the answers so far. It is true that you can access such properties via for-in loop. However, it might be important to know that for-in loop gives keys as strings, not as numbers as you might expect:

var obj = {1:2};
for (var key in obj) {
    alert(typeof(obj[key])); // you get "number" as expected, however
    alert(typeof(key)); // you get "string", not "number"
}

A similar thing happens during serialization with JSON:

JSON.stringify( {1:2} ) === '{"1":2}'

So if you code depends on this little detail you better be aware of it.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRobert RochaView Question on Stackoverflow
Solution 1 - JavascriptTomView Answer on Stackoverflow
Solution 2 - JavascriptRobGView Answer on Stackoverflow
Solution 3 - JavascriptTed HoppView Answer on Stackoverflow
Solution 4 - JavascriptSteven WexlerView Answer on Stackoverflow
Solution 5 - JavascriptGalen LongView Answer on Stackoverflow
Solution 6 - JavascriptEugene VeselovView Answer on Stackoverflow