使用for of遍历可迭代数据时,会调用其[Symbol.Iterator]方法。

目前有[Symbol.iterator]方法的数据类型有:

  • 字符串 String
  • 数组 Array
  • 映射 Map
  • 集合 Set
  • arguments对象
  • Nodelist等DOM集合

Number与Object实例无[Symbol.iterator]方法,如果要使用for of遍历对象,便需要重写其[Symbol.iterator]方法

第一步:重写Object实例的[Symbol.iterator]方法

  • 使用next函数
  • 可以根据需要遍历,本次以遍历value为例
    • 遍历对象的值,使用:Object.values(obj),本案例使用该方法
    • 遍历对象的键,使用:Object.keys(obj)
    • 遍历对象的键/值,使用:Object.entries(obj) ```javascript let obj = {name:’zhangsan’,age:18,habby:’basketball’}

// 重写[Symbol.iterator]方法 obj[Symbol.iterator] = function(){ let index = 0 // 返回next函数 return { // next函数需要返回两个参数:每次迭代返回的值value,迭代是否结束的标志done next(){ let values = Object.values(obj) // 取出对象的所有值,写在next方法中可以避免在迭代过程中obj发生变化 if (index < values.length){ return { done:false, // 遍历还未结束 value:values[index++] // index++先运算,再加1 } }else{ return { done:true // 遍历结束 } } }, // 在for of中提前中止迭代,会自动调用这个return方法(比如break,continue,throw等) return(){ console.log(‘Exiting early’) return {done:true} } } }

  1. <a name="UVuzm"></a>
  2. ### 第二步,使用for of遍历对象
  3. ```javascript
  4. for (let k of obj){
  5. console.log(k) // zhangsan 18 basketball
  6. }
  7. /*---------*/
  8. for (let k of obj){
  9. if (k==18){
  10. continue
  11. }
  12. console.log(k) //zhangsan basketball Exiting early
  13. }
  14. /*---------*/
  15. for (let k of obj){
  16. if (k==18){
  17. break
  18. }
  19. console.log(k) //zhangsan Exiting early
  20. }

拓展

  • 重写后的[Symbol.iterator]其实就是一个生成器
    • 生成器中本身就具有next,return,throw方法
    • 以下写法未解决,在调用next方法的过程中,对象发生变化的情况 ```javascript let obj = {name:’zhangsan’,age:18,habby:’basketball’}

// 重写[Symbol.iterator]方法,function加上号表示生成器函数 obj[Symbol.iterator] = function(){ let values = Object.values(obj) // yield加上表示挨个取出里面的元素 yield values } ```

补充:

可迭代对象,可以使用以下方法:

  1. for-of 循环
  2. 数组解构
  3. 扩展操作符
  4. Array.from()
  5. 创建集合
  6. 创建映射
  7. Promise.all()接收由期约组成的可迭代对象
  8. Promise.race()接收由期约组成的可迭代对象
  9. yield*操作符,在生成器中使用