上代码
先遍历某个对象
const obj = {
a: 1,
b: 2,
c: 3
}
for (let i in obj) {
console.log(i)
// a
// b
// c
}
for (let i of obj) {
console.log(i)
// Uncaught TypeError: obj is not iterable 报错了
}
再遍历一个数组
const arr = ['a', 'b', 'c']
// for in 循环
for (let i in arr) {
console.log(i)
// 0
// 1
// 2
}
// for of
for (let i of arr) {
console.log(i)
// a
// b
// c
}
const arr = ['a', 'b']
// 手动给 arr数组添加一个属性
arr.name = 'qiqingfu'
// for in 循环可以遍历出 name 这个键名
for (let i in arr) {
console.log(i)
// a
// b
// name
}
for in 的特点
结合上面的两个例子,分析得出:
for ... in 循环返回的值都是数据结构的 键值名。
遍历对象返回的对象的key值,遍历数组返回的数组的下标(key)。
for ... in 循环不仅可以遍历数字键名,还会遍历原型上的值和手动添加的其他键。如——例3
特别情况下, for ... in 循环会以任意的顺序遍历键名
for...in适合遍历对象
for of 特点
for of 循环用来获取一对键值对中的值,而 for in 获取的是 键名
一个数据结构只要部署了 Symbol.iterator 属性, 就被视为具有 iterator接口, 就可以使用 for of循环。
例1这个对象,没有 Symbol.iterator这个属性,所以使用 for of会报 obj is not iterable
for of 不同与 forEach, 它可以与 break、continue和return 配合使用,也就是说 for of 循环可以随时退出循环。forEach,Map等可以使用try...catch来中断循环(在你希望终止的地方抛个error)。
哪些数据结构部署了 Symbol.iteratoer属性了呢?
只要有 iterator 接口的数据结构,都可以使用 for of循环
- 数组 Array
- Map
- Set
- String
- arguments对象
- Nodelist对象, 就是获取的dom列表集合
以上这些都可以直接使用 for of 循环。 凡是部署了 iterator 接口的数据结构也都可以使用数组的 扩展运算符(...)、和解构赋值等操作。
我也想让对象可以使用 for of循环怎么办?
------------------------------
使用 Object.keys() 获取对象的 key值集合后,再使用 for of
const obj = {
a: 1,
b: 2,
c: 3
}
for (let i of Object.keys(obj)) {
console.log(i)
// 1
// 2
// 3
}
-------------
或者续上一个迭代器
let obj = {
0: 'a',
1: 'b',
2: 'c',
length: 3,
[Symbol.iterator]: function () {
// index用来记遍历圈数
let index = 0;
let next = () => {
return {
value: this[index],
done: this.length == ++index
}
}
return {
next
}
}
}
// console.log(obj.length)
console.log([...obj]);//(2) ["a", "b"]
for(let p of obj){
console.log(p) //"a" "b"
}