for-in 用于 数组和对象
for-in更适合遍历对象,通常是建议不要使用for-in遍历数组
var arr = ['a','b','c','d']; for(var i in arr) { console.log(i); // 0 1 2 3 } console.log('---------------'); var obj = {a:'a', b:'b', c:'c'}; for(var i in obj) { console.log(i); // a,b,c }
let a = [1, 2, 3]; let ao = {a:'com', b:'org', c:'top'}; let as = 'six'; for (const key in a) { console.log(a[key]); } //1 //2 //3 for (const key in ao) { console.log(ao[key]); } //com //org //top for (const key in as) { console.log(as[key]); } //s //i //x
- 数组糟糕的选择
- key为string类型,可能会意外导致如:'2' + 1 == '21'
- 在某些情况下,这段代码可能按照随机顺序遍历数组元素
- 除了遍历数组元素外,还会遍历自定义属性,如果你的数组中有一个可枚举属性 myArray.name,循环将额外执行一次,遍历到名为“name”的索引,就连数组原型链上的属性都能被访问到
- 简而言之,for-in 是为普通对象设计的,你可以遍历得到字符串类型的键,因此不适用于数组遍历。
for-of用于 arr map set string
var arr2 = ['a','b','c','d']; for(i of arr2) { console.log(i); // a,b,c,d } console.log('---------------'); var maps = new Map([['one',1],['two',2],['three',3]]); for([key, value] of maps) { console.log(`Key: ${key} and Value: ${value}`); // Key: one and Value: 1 Key: two and Value: 2 Key: three and Value: 3 } var sets = new Set([1,1,2,2,3,3]); for(value of sets) { console.log(value); //1 2 3 } var str = 'javascript'; for(value of str) { console.log(value);//'j','a','v' }
从性能上看。for循环 > for-of > forEach > for-in
forEach只能用于数组。
实际应用的问题
通常情况下,不建议使用 for-in 来遍历数组,除非你知道这个数组对象中没有这样的属性
数组空项
假设要遍历的数组张这样:array = ['a', , 'c']
// a undefined c
for (let index = 0; index < array.length; index++) {
const element = array[index]
console.log(element) // 没有跳过空值
}
// a c
array.forEach(element => {
console.log(element) // 跳过空值
})
// a c
for (const key in array) {
console.log(array[key]) // 跳过空值
}
// a undefined c
for (const iterator of array) {
console.log(iterator) // 没有跳过空值
}
上面几个遍历方法,只有 forEach 和 for-in 遍历会跳过空值,值得注意的是,如果空值明确设置为 undefined 如 ['a', undefined, 'c']
那么所有遍历方法都能够将 undefined 遍历出来
实际应用的问题
在 JSON 中是不支持这样的空值的,如果在 parse 方法调用时传入的 JSON 字符串数据含有空值,会报错:
JSON.parse('["a", , "c"]')
// 所以建议使用 for-of 或 for 循环进行遍历,因为如果
- stringify 方法调用时,空值会被转为 null 非空值或 undefined
- 正确的做法应该是保持 undefined,遍历使用 for-of 或 for 循环
建议使用 for-of
let a = [1, 2, 3]; let ao = {a:'com', b:'org', c:'top'}; let as = 'six'; let am = new Map([['a', 1], ['b', 2]]); let ass = new Set([1, 2, 2, '2', '3']); for (const item of a) { console.log(item); } //1 //2 //3 for (const key of Object.keys(ao)) { console.log(ao[key]); } //com //org //top for (const item of as) { console.log(item); } //s //i //x for (const [key, item] of am) { console.log(key) console.log(item) } //{o:'233'} //1 //b //2 for (const key of ass) { console.log(key) } //1 //2 //2 //3