面试 - 剖析 for...of循环

本文详细剖析了JavaScript中的for...of循环,探讨其工作原理、应用场景和与传统循环的区别,帮助开发者更好地理解和使用这一特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
 * for of循环作为遍历所有数据结构的统一方式;
 * 优点:
 1. for (item of arr){}直接用的是item每一项,类似于arr.forEach
 2. 相较于forEach,for of能用break直接终止循环,但forEach无法终止遍历,可以用some或是every返回true或false终止遍历
 3. 伪数组也可以用for of遍历
 * */

//遍历set
const s = new Set([1, 2, 32]);
for (let item of s) {
  console.log("---item---", item);
}

//遍历Map
const m = new Map();
m.set("name", "hguan");
m.set("age", 26);
for (let [key, value] of m) {
  //item 是['age',26],可以直接用解构
  console.log("item", key, value);
}

//遍历 obj    但是报错 :obj is not iterable--------解决的方法就是实现可迭代的[interable]
// const obj = { name: "hguan", title: "离职了" };
// for (let item of obj) {
//   console.log("-----item-------", item);
// }

/**
 * for of循环的实现原理:
 * 1.  es2015提供了iterable接口(也叫规格标准),例如任何一种类型都有toString方法,说明他们都实现了统一的接口
 * 2.  iterable接口是for ...of的前提;
 * 可以用symbol.iterator属性拿到这个iterator函数: arr[symbol.iterator]()
 * 调用后,返回一个数组的迭代器对象;对象中有一个next方法,调用后返回一个对象{value:'',don:false};
 * 不断调用next方法就可以实现对数据的遍历
 * 3.for of内部的工作原理: 就是不断调用 iterator.next()实现遍历
 */
const ss = new Set([1, 2, 3, 4, 5]);
const iterator = ss[Symbol.iterator](); //返回一个对象 [Set Iterator] { 1, 2, 3, 4, 5 }
console.log("iterator.next();", iterator.next());
console.log("iterator.next();", iterator.next());
console.log("iterator.next();", iterator.next());
console.log("iterator.next();", iterator.next());

// ----------------------迭代器模式------------------------------
const _obj = {
  //interable
  arr: [1, 2, 3, 4, 5, 6, 7],
  [Symbol.iterator]: function () {
    let index = 0;
    return {
      //interator
      next: () => {
        //目的是让this为父作用域的this
        return {
          //interationResult
          value: this.arr[index],
          done: index++ >= this.arr.length,
        };
      },
    };
  },
};
for (let item of _obj) {
  console.log("-----item-----", item);
}
//释疑
let i = 0;
console.log("i++", i++, i); //i++ 0 1
let j = 0;
console.log("++j", ++j, j); //++j 1 1

//--------------------------迭代器的应用----------------------------
//需求:这是一个不断会增加的清单对象,想让你罗列出所有的item?
const todos = {
  life: ["冥想", "吃饭", "健身", "睡觉"],
  learn: ["语文", "英语", "数学", "数学", "历史"],
  plan: ["结交朋友", "周末出游"],
};
//法1:整合到一个数组中遍历
const values = Object.values(todos);
const targetArr = [].concat(...values);
for (let item of targetArr) {
  console.log("-----item----", item);
}

//法2:使用迭代器,需要代码实现iterator方法
const _todos = {
  life: ["冥想", "吃饭", "健身", "睡觉"],
  learn: ["语文", "英语", "数学", "数学", "历史"],
  plan: ["结交朋友", "周末出游"],
  [Symbol.iterator]: function () {
    //整合到一个数组
    const all = [].concat(this.life, this.learn, this.plan);
    let index = 0;
    return {
      next: () => {
        return {
          value: all[index],
          done: index++ >= all.length,
        };
      },
    };
  },
};
for (let item of _todos) {
  console.log("-------all数组里的每个item------", item);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值