为什么数组中的数字元素的类型被评估为javascript中的字符串

时间:2016-07-22 14:58:48

标签: javascript

例如

var a = [1, 2, 3];
for (var i in a) {
    console.log(typeof i);
}

输出

string
string
string

我是一名Python程序员,我发现它非常不直观。为什么不将元素评估为数字呢?

2 个答案:

答案 0 :(得分:5)

您正在循环对象的keys。这意味着您实际测试的键是“0”,“1”,“2”。

您可以在此处看到,如果您还安装了i。此外,如果您控制位于该数组中该索引处的值,并对其进行测试,您将看到它是一个数字:

var a = [1, 2, 3];
for (var i in a) {
  console.log(i, typeof i, a[i], typeof a[i]);
}

在ES5中,向循环遍历其值(和索引)的数组添加了一项新功能:Array#forEach

var a = [1, 2, 3];
a.forEach(function(v) {
  console.log(v, typeof v);
});

在ES2015 +中,添加了for-of,它将使用for样式循环遍历值:

// ES2015+ only!!
let a = [1, 2, 3];
for (let v of a) {
  console.log(v, typeof v);
}

答案 1 :(得分:3)

  

为什么数组中数字元素的类型被评估为javascript中的字符串

如果你的意思是元素,而不是索引,那么问题在于你只是在看错误的类型。请参阅KevBot's answer

如果你问为什么索引(0,1和2)是字符串而不是数字,因为数组索引通常是数字,这是因为JavaScript中的标准数组根本不是数组,它们只是具有一些special behavior的对象:

  

Array对象是一个奇特的对象,它对数组索引属性键进行了特殊处理(参见6.1.7)。属性名称为数组索引的属性也称为元素。每个Array对象都有一个length属性,其值始终是小于2 32 的非负整数。 length属性的值在数值上大于名称为数组索引的每个属性的名称;无论何时创建或更改Array对象的自有属性,都会根据需要调整其他属性以保持此不变量。具体来说,每当添加名称为数组索引的属性时,length属性的值将根据需要更改为该数组索引的数值之一;并且每当更改length属性的值时,将删除其名称为值不小于新长度的数组索引的每个属性。此约束仅适用于Array对象的自有属性,不受length或可从其原型继承的数组索引属性的影响。

在ES2015之前,所有对象属性名称都是 strings 。 (现在它们可以是字符串或符号。)数组索引只是符合specific definition的属性名称:

  

当且仅当ToString(ToUint32(P))等于 P 并且ToUint32(P)不等于2时,字符串属性名称​​ P 是一个数组索引 32 -1。

另请参阅A myth of arrays (在我的博客上)