for...in 和 for...of的区别
每天对自己多问几个为什么,总是有着想象不到的收获。
1、对数组的遍历
//for...in let arr = [1,2,3] for(let key in arr) { console.log(key); // 0 // 1 // 2 } //for...of let arr = [1,2,3] for(let key of arr) { console.log(key); // 1 // 2 // 3 }
总结一: for…in 返回key值, for…of返回value值
2、对 对象的遍历
// for...in let obj = { name: james, age: 12 } for(let key in obj) { console.log(key) //name //age } // for...of let obj = { name: james, age: 12 } for(let key of obj) { console.log(key) // 报错:obj is not iterable }
总结二: for…in 遍历对象,返回key值,for…of遍历对象,会直接报错, 因为缺少Symbol.iterable
可迭代对象包括: Array,Map,Set,String,TypedArray,arguments等等
3、添加原型上添加属性(for…in)或者手动添加属性
Array.prototype.key1 = function() { } let a = [1,2,3] a.foo = james for(let key in a) { console.log(key); //0 //1 //2 //james //key1 key1是可以被枚举的,就会被打印出来 } Array.prototype.key1 = function() { } //设置key1为不可枚举 Object.defineProperty(Array.prototype, key1, { enumerable: false }) let a = [1,2,3] for(let key in a) { console.log(key); //0 //1 //2 }
总结三: for…in会遍历可枚举的属性(包括在原型链上)。for…of不会遍历原型链上
4、遍历Map,Set结构(针对for…of)
//for...of let map = new Map([[11, james], [22, kobe]]) for(let key of map) { console.log(key); //[11, james] //[22, kobe] } //for...in let map = new Map([[11, james], [22, kobe]]) for(let key in map) { console.log(key); //没有任何输出 } // 其中Set的效果也是一样的的
结论四: for…in 不能循环Map Set的数据结构 , for…of输出数组的value值
归纳总结
for…in对key值的排序(特别之处)
代码如下:
let obj = { name: james } obj[11] = a obj[2] = b obj[age] = 12 obj[33] = 33 obj[sex] = 男 obj[1] = 男人 for(let key in obj) { console.log(key); // 1 // 2 // 11 // 33 // name // age // sex }
看上面的打印结果,先打印数字,在打印字符串。
规则:先对数字跟大小顺序输出,然后在输出字符串(按照先后顺序)