模拟面试场景
面试官:你知道for...of和for...in的区别吗?
求职者:for...in可以遍历对象和数组,for...of只可以遍历数组
面试官:为什么会出现上述的情况?
求职者:。。。
for...of
ES6新增的可以遍历数据结构的一个方式,但是可以遍历的前提是该数据结构具有Symbol.iterator属性,也就是说不论数组或者对象,只要具有Symbol.iterator属性就可以遍历。原理是遍历数据结构的Iterator接口,将for...of循环分解成最原始的for循环。
//数组
const arr = ['a','b','c']
for(let item of arr){
console.log(item) //a,b,c
}
//对象
const obj = {};
obj[Symbol.iterator] = arr[Symbol.iterator].bind(arr]
for(let item of obj){
console.log(item) //a,b,c
}
数组默认具有Symbol.iterator属性,对象没有默认部署该属性,是因为对象属性的遍历顺序不能确定,需要手动指定。也就是说,单纯的声明一个Object对象是不可以用for...of去遍历的,这个坑被ES6的Map结构给填上了。
默认具体Symbol.iterator属性的有:Array、Map、Set、String、TypedArray、函数的 arguments 对象、NodeList 对象
for...in
for...in是ES3遍历数据结构key值的一种方式,对于对象和数组都可以遍历,但是会将当前数据结构的原型链上的可枚举属性都遍历出来,可以通过hasOwnProperty来判断是否是私有属性。
//数组
const arr = ['a','b','c'];
for(let key in arr){
console.log(key) //0,1,2
}
//对象
const obj = {name:'alhh',age:18};
for(let key in obj){
console.log(key) //name,age
}
总结
- for...of遍历的是item,for...in遍历的是key值;
- 具有Symbol.iterator属性的才可以使用for...of进行遍历,for...in不需要,可以直接遍历数组、对象;
- for...in会将原型链上的属性都遍历出来,for...of不会;
- for...of支持return,for...in不支持。