只要一个数据结构部署了Iterator接口,就可以使用for…of…进行遍历循环,也可以说for…of…是遍历所有部署了Iterator接口的数据结构的统一方法
总结下for…in…与for…of…的区别,一般情况下,for…in…用于遍历对象,for…of…用于遍历数组及部署了Iterator接口的数据结构
数组
数组原生具有Iterator接口,可以直接使用for…of…进行遍历循环
const arr = [1,2,3];
let iter = arr[Symbol.iterator]();
//两种写法是等价的
for(let v of arr ) {
console.log(v) // 1,2,3
}
for(let v of iterator ) {
console.log(v) // 1,2,3
}
1、for…in…循环读取键名,而for…of…循环读取键值
const arr = [1,2,3];
//且for...in...循环返回的是键名的字符串表达
for(let i in arr) {
console.log(i) // '0' , '1', '2'
}
for(let i of arr) {
console.log(i) //1,2,3
}
2、for…of…循环调用遍历器接口,数组的遍历器接口只返回具有数字索引的属性,for…in…还会遍历手动添加的其他键
const arr = [1,2,3];
arr.name = "array";
for(let i in arr){
console.log(i) // '0','1','2','name'
}
for(let i of arr){
//不会返回数组的name属性
console.log(i) // 1,2,3
}
对象:
for…in…
const obj = {
name: 'Gary',
age: 16
};
for(let i in obj) {
console.log(i , obj[i]) // 'name' 'Gary'
} // 'age' 16
for…of…
普通对象无法直接使用for…of…进行遍历,会报错;
解决:使用Object.keys()将对象的键名生成一个数组,然后遍历这个数组
const obj = {
name: 'Gary',
age: 16
};
for( let i of Object.keys(obj)){
console.log( i , obj[i]) //'name' 'Gary'
} //'age' 16
插播一条:数组的for…of…与forEach()的区别
forEach()无法中途跳出循环,break命令或return命令都不管用,甚至会报错
但是for…of…可以与break continue return 配合使用
const arr = [1,2,3,500];
for(i of arr) {
if(i > 100) {
break
}
console.log(i) // 1,2,3
}
for(i of arr) {
if(i === 3) {
continue
}
console.log(i) // 1,2,500
}
const arr = [1,2,3,500];
arr.forEach(item => {
if(item > 100){
//这里会报错
break
}
console.log(item)
})