for in遍历的是数组的索引(index),而for of遍历的是数组元素值(value)
1、for…in 循环:只能获得对象的键名,不能获得键值, for…of 循环:允许遍历获得键值
let arr = ['张三','李四','王五'];
for(let item in arr){
console.log(item);
}
//0,1,2
for(item of arr){
console.log(item);
}
//张三 李四 王五
2、对于普通对象,没有部署原生的 iterator 接口,直接使用 for…of 会报错
let obj = {
name:'张三',
age:18
}
for of 会报错
for(let item of obj){
console.log(item);
}
// Uncaught TypeError: obj is not iterable
//for in 可以遍历键名
for(let item in obj){
console.log(item);
}
//name age
//也可以使用Object.keys(obj) 方法将对象的键名生成一个数组,然后遍历这个数组
for(let item of Object.keys(obj)){
console.log(item);
}
//name age
3、for…in 循环不仅遍历数字键名,还会遍历手动添加的其它键,甚至包括原型链上的键。for…of 则不会这样
let arr1 = [1,2,3]
arr1.abc = 'hello'
Array.prototype.name = 'world'
for(let item in arr1){
console.log(item);
}
//0 1 2 abc name
for(let item of arr1) {
console.log(item)
}
//1,2,3
4、forEach 循环无法中途跳出,break 命令或 return 命令都不能奏效
let arr2 = [1, 2, 3, 5, 9]
arr2.forEach(item => {
if(item % 2 === 0) {
return
}
console.log(item)
})
//1 3 5 9
//for...of 循环可以与break、continue 和 return 配合使用,跳出循环
for(let item of arr2) {
if(item == 2) {
break
}
console.log(item)
}
// 1
for(let item in arr2) {
if(item == 2) {
break
}
console.log(item)
}
// 0 1
5、无论是 for…in 还是 for…of 都不能遍历出 Symbol 类型的值,遍历 Symbol 类型的值需要用 Object.getOwnPropertySymbols() 方法
function fn(){
let a = Symbol('a')
let b = Symbol('b')
let obj = {
[a]: '张三',
[b]: '李四',
c: '王五',
d: '赵六'
}
for(let item in obj){
console.log(item);
}
//c d
let oSymbols = Object.getOwnPropertySymbols(obj)
console.info(oSymbols)
// [Symbol(a), Symbol(b)]
oSymbols.forEach(item => {
console.info(item.toString() + ' --> ' + obj[item])
})
//Symbol(a) --> 张三 Symbol(b) --> 李四
// Reflect.ownKeys 方法可以返回所有类型的键名,包括常规键名和Symbol键名
let keyArray = Reflect.ownKeys(obj)
console.log(keyArray) // ["c", "d", Symbol(a), Symbol(b)]
}
fn()