共同点:for…of与for…in都是用来循环遍历数据的。
不同点:
1、for…of是es6中的,for…in是es5中的
2、当遍历数组中每一项值时,明显for…of更方便
var arr = ['a','b','c'];
// for...in循环遍历的是数组的索引,再通过索引值获取数组值
for (const key in arr) {
console.log(key); // 0,1,2
console.log(arr[key]); // a b c
}
// 而for...of循环遍历的是数组的值
for (const item of arr) {
console.log(item); // a b c
}
3、当遍历自定义对象时,for…of会报错,明显for…in最佳
// for...in循环遍历的是对象的键值,再通过键值获取对应的值
var obj = {id:1,name:'d',age:30}
for (const key in obj) {
console.log(key,obj[key]);
}
//for...of报错
for (const item of obj) {
console.log(item);
}
综上所述:遍历数组时,for…of最佳,遍历对象时,for…in最佳。
为什么遍历自定义对象时,for…of会报错呢,咱们不能因为可以使用for…in来解决这个问题,就可以不去探究为啥用for…of就不行。
原来,for of可以遍历ES6中iterable类型的数据类型,Array、Map和Set都属于iterable类型,而Object没有默认部署 Iterator 接口,因为对象的哪个属性先遍历,哪个属性后遍历是不确定的,需要开发者手动指定,如果非要用for of遍历自定对象,也是可以实现的,实现步骤如下:
方法一:
var obj = { id: 1, name: 'd', age: 30 }
obj[Symbol.iterator] = function () {
var keys = Object.keys(this);
var count = 0;
return {
next() {
if (count < keys.length) {
return { value: obj[keys[count++]], done: false };
} else {
return { value: undefined, done: true };
}
}
}
};
for (const item of obj) {
console.log(item);
}
方法二: Symbol.iterator 接口其实是一个 Generator 函数,所以可以简写成以下代码:
obj[Symbol.iterator] = function*(){
var keys = Object.keys(obj);
for(var k of keys){
yield [k,obj[k]]
}
};
for(var [k,v] of obj){
console.log(k,v);
}