为什么Object.keys返回字符串数组而不是数字数组

40

当我运行以下代码时:

var obj = { 0: 'a', 1: 'b', 2: 'c' };
typeof Object.keys(obj)[0] //returns string

在我创建obj对象时,我正在创建数字键。

为什么键是字符串而不是number


2
对象属性不能使用数字键,对象属性始终为字符串。 - Marc Dix
如果您需要使用数字作为键,请使用ES2015 Map - user5536315
但我们也可以通过 obj[0] 来实现,其中 0 是数字, 我只是想知道他们这样处理的特定原因。 - Jagdish Idhate
我猜答案没有回答到我的问题, 我不想要绕过的方法, 在制作Object.keys函数时,javascript社区犯了错误吗? - Jagdish Idhate
"0" 被强制转换为字符串。 - Nina Scholz
6个回答

40

始终 是字符串类型。如果需要使用数字,您需要手动进行类型转换:

var obj = { 0: 'a', 1: 'b', 2: 'c' };
var ids = Object.keys(obj).map(Number);

console.log(ids);


从技术上讲,如果我正确理解JS的话,它们也可以是符号。 - axel22

23
因为 Object.keys 返回一个由字符串组成的数组。

Object.keys() 方法返回一个数组,该数组的元素是直接在对象上找到且可枚举的属性名称。属性的顺序与手动遍历对象属性时的顺序相同。

你会得到一个字符串数组,因为按照定义,属性名 就是字符串。

属性名必须是字符串类型。这意味着非字符串对象不能用作对象中的键值。任何非字符串对象,包括数字,都会通过 toString 方法被强制转换为字符串。


@pvg,虽然*toString不是一个转换,但它返回任何对象的字符串表示形式,包括字符串。这是mdn所述的真实情况。 - Nina Scholz
1
啊,现在将其作为引用更有意义了。尽管来自 MDN,但它仍然是完全错误的转换,而不是强制类型转换,即使不考虑“typecasted”不符合语法的抱怨。 - pvg

4
根据文档,Object.keys() 返回字符串数组。 Object.keys() 返回一个数组,其元素是与对象直接关联的可枚举属性对应的字符串。属性的顺序与手动循环遍历对象的属性时给定的顺序相同。(引用自此处
如果您想将其转换为数字数组,则可以使用map()

var obj = {
  0: 'a',
  1: 'b',
  2: 'c'
};
console.log(typeof Object.keys(obj).map(Number)[0])


2

Javascript对象没有数字键!所有的键都是字符串。一直以来都是这样。

如果你想将其他东西映射到值上,你应该使用一个Map


0

var obj = {
  0: 'a',
  1: 'b',
  2: 'c'
};
console.log(typeof Object.keys(obj).map(Number)[0])


6
你应该在回答中给出解释,而不仅仅是发布源代码。 - Roberto Linares

0

这里有一些与类型安全相关的内容需要小心注意,尤其是一些高评价答案(例如 Object.keys(obj).map(Number)),在 .js 中有很多边缘情况,如果映射到Number,您可能会得到错误的结果。在使用对象键时不太常见,但总会有奇怪的地方,比如为什么 Number([]) === 0...

在这个 Object.keys() 的示例中,如果你有一个混合类型的对象,它们不能安全地转换为数字类型,你最终会将所有东西都转换为 NaN:

Object.keys({ "a": "1", 2: "2" }).map(Number) 
// -> [NaN, 2]
// :(

您可以在 map 方法中加入一些花样,它会优雅地处理非数字键:

Object.keys({ "a": "1", 2: "2" }).map((k) => Number.isNaN(Number(k)) ? k : Number(k)
// -> ["a", 2]
// :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接