for of循环
遍历所有数据结构的统一方式,只要这种数据结构有自己的ierable接口
for…of循环就是调用了被遍历对象的iterator方法得到一个迭代器,从而去遍历内部所有的数据
可以使用break跳出循环
// for...of 循环const arr = [100, 200, 300, 400]// for (const item of arr) {// console.log(item)// }// for...of 循环可以替代 数组对象的 forEach 方法// arr.forEach(item => {// console.log(item)// })// for (const item of arr) {// console.log(item)// if (item > 100) {// break// }// }// forEach 无法跳出循环,必须使用 some 或者 every 方法// arr.forEach() // 不能跳出循环// arr.some()// arr.every()// 遍历 Set 与遍历数组相同// const s = new Set(['foo', 'bar'])// for (const item of s) {// console.log(item)// }// 遍历 Map 可以配合数组结构语法,直接获取键值// const m = new Map()// m.set('foo', '123')// m.set('bar', '345')// for (const [key, value] of m) {// console.log(key, value)// }// 普通对象不能被直接 for...of 遍历// const obj = { foo: 123, bar: 456 }// for (const item of obj) {// console.log(item)// }
迭代器Iterator
// 迭代器(Iterator)const set = new Set(['foo', 'bar', 'baz'])const iterator = set[Symbol.iterator]()// console.log(iterator.next())// console.log(iterator.next())// console.log(iterator.next())// console.log(iterator.next())// console.log(iterator.next())while (true) {const current = iterator.next()if (current.done) {break // 迭代已经结束了,没必要继续了}console.log(current.value)}
实现可迭代接口Iterable
就是挂载一个iterator方法,然后在方法中实现迭代器对象
// 实现可迭代接口(Iterable)// const obj = {// [Symbol.iterator]: function () {// return {// next: function () {// return {// value: 'zce',// done: true// }// }// }// }// }const obj = {store: ['foo', 'bar', 'baz'],[Symbol.iterator]: function () {let index = 0const self = thisreturn {next: function () {const result = {value: self.store[index],done: index >= self.store.length}index++return result}}}}for (const item of obj) {console.log('循环体', item)}
迭代器设计模式
迭代器模式的核心意义:对外提供统一遍历的接口,让外面不需要关心内部的数据结构是怎样的
感受:就像是以前遍历需要使用某种具体的数据结构的独有的遍历方法,例如数组的forEach,而使用该模式,只要在数据结构内部实现可迭代接口,所有数据都只要for of就可以遍历到里面的数据了了
// 迭代器设计模式// 场景:你我协同开发一个任务清单应用// 我的代码 ===============================const todos = {life: ['吃饭', '睡觉', '打豆豆'],learn: ['语文', '数学', '外语'],work: ['喝茶'],// 提供统一遍历访问接口each: function (callback) {const all = [].concat(this.life, this.learn, this.work)for (const item of all) {callback(item)}},// 提供迭代器(ES2015 统一遍历访问接口)[Symbol.iterator]: function () {const all = [...this.life, ...this.learn, ...this.work]let index = 0return {next: function () {return {value: all[index],done: index++ >= all.length}}}}}// 你的代码 ===============================// for (const item of todos.life) {// console.log(item)// }// for (const item of todos.learn) {// console.log(item)// }// for (const item of todos.work) {// console.log(item)// }todos.each(function (item) {console.log(item)})console.log('-------------------------------')for (const item of todos) {console.log(item)}
