当我这样做时:
const foo = [0, 1, 2]
for (i = 0; i < foo.length; i ++){
console.log(foo[i], typeof foo[i])
}
我得到这个:
0 number
1 number
2 number
但当我这样做时:
for (let item in foo){
console.log(item, typeof item)
}
我得到这个:
0 string
1 string
2 string
这是怎么回事??我需要知道什么规则才能预测这一点?
编辑:我正在运行节点12.18.3
这里没有强制实际上,您正在使用两个不同的循环迭代两种不同的基元类型。
传统的for
循环使用计数器,计数使用数字。
for/in
循环用于迭代对象的属性。对象具有键/属性,这些键/属性始终是字符串。因此,当您看到0
、1
和2
时,您看到的是字符串"0"
、"1"
和"2"
。
因此,当您在array
实例上使用for/in
循环时,它是由Array
对象的键枚举的,这些键包括数组索引的字符串表示以及Array
实例的任何可枚举属性。然后,您可以枚举数组中除了项目之外的其他属性,如下所示:
const foo = [0, 1, 2];
// Add a property to the array instance
foo.bar = "baz";
for (let item in foo){
// This will log ALL the enumerable properties
// of the object, in this case, including properties
// that are not the array values.
console.log(item, foo[item]);
}
这是另一种方式。下面是用for/in
枚举的对象文字。请注意,当创建文字时,键不会在它们周围加引号,但当测试它们的类型(它们是键名称,而不是键值(时,它们被报告为字符串,因为它们隐含地是:
let obj = {
key1: "something",
key2: "something else",
foo: 42,
false: true,
99: 100
};
for(let prop in obj){
// Note that even the unquoted key name of
// false is implicitly a string, not a Boolean
// and the 99 key is a string, not a number
console.log(prop, "(" + typeof prop + ")", obj[prop], "(" + typeof obj[prop] + ")");
}
如文件中所述(以上链接(:
for。。。in语句遍历由字符串键控的对象(忽略由符号键控的(,包括继承的可枚举属性。
基本上混合了数组的值(在经典for
中调用foo[i]
时的第一个循环(和数组的键/索引(在调用for ... in ...
时(。
只要尝试使用foo = [5,6,7]
,您就会清楚地看到差异。
for (let a in [5,6,7])
console.log(a, typeof a)
正如Scott Marcus的另一个答案所说,索引就像键一样,在这里是字符串。
还要注意,如果您希望在数组(或可枚举(的所有元素上循环,请使用for ... of ...
:
for (let a of [5,6,7])
console.log(a, typeof a)