javascript 对象属性名称作为数字
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16908476/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Object property name as number
提问by Robert Rocha
According to the official JavaScript documentationyou can define object literal property names using integers:
根据官方 JavaScript 文档,您可以使用整数定义对象文字属性名称:
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?
我的问题是,您如何引用以整数作为名称的属性?我尝试了通常me.123
但出现错误。我能想到的唯一解决方法是使用for-in
循环。有什么建议?
回答by Tom
You can reference the object's properties as you would an array and use either me[123]
or me["123"]
您可以像引用数组一样引用对象的属性,并使用me[123]
或me["123"]
回答by RobG
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.
点表示法仅适用于作为有效标识符的属性名称。标识符必须以字母、$、_ 或 unicode 转义序列开头。对于所有其他属性名称,您必须使用括号表示法。
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 +=+
回答by Ted Hopp
You can use me[123]
or me["123"]
. Both work.
您可以使用me[123]
或me["123"]
。两者都有效。
回答by Steven Wexler
You can use bracket notationme[123]
.
您可以使用括号表示法me[123]
。
回答by Galen Long
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 Setscheck 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]]
)并将其转换为嵌套对象,以便我们可以检查该对是否在 O(1) 时间的对象中(例如{0: {0: true, 1: true}, 1: {2: true}, 2: {3, true}}
)。请注意,集合检查引用相等而不是值相等,因此我们无法将配对本身存储在集合中并获得相同的结果:
// [[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
回答by Eugene Veselov
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:
数字属性名称的情况似乎比迄今为止的答案中解释的要复杂。您确实可以通过 for-in 循环访问这些属性。但是,了解 for-in 循环将键作为字符串而不是您期望的数字提供可能很重要:
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 进行序列化期间会发生类似的事情:
JSON.stringify( {1:2} ) === '{"1":2}'
So if you code depends on this little detail you better be aware of it.
所以如果你的代码依赖于这个小细节,你最好意识到它。