美文网首页
Iterator详解

Iterator详解

作者: zhangxt456 | 来源:发表于2018-11-07 10:38 被阅读0次

1.什么是for-of循环

对于如下一个数组,便利其中的值,方法有哪些?

var arr = ['a', 'b', 'c'];

首先想到的就是for循环

for(var i = 0; i++; i<arr.length){
  console.log(arr[i])
}

如果了解es5,还可以用for-in

for(var i in arr){
  console.log(arr[i])
}

然而还有另外一种遍历方法for-of

for(var ch of arr){
  console.log(ch)
}

使用for-of时,ch不是arr的索引,而是其中的value值
for-of相比for-in的独特之处:

let arr = 'abc'
for(var char of arr){
  console.log(char)
}
//输出a,b,c

但是for-in是无能为力的。for-of不仅可以对数组和字符串遍历,还可以适用于集合:Map,Set,NodeList。NodeList是DOM对象集合。

2、迭代器(Iterator)实现原理

var obj = {0:'abc',1:'def'}
for(var value of obj){
  console.log(value)
}

运行后会报错,表明字面量对象是不可遍历的。如果要像Array,String等对象一样支持for-of遍历,可以像Array,String等对象一样,在他们的原型上,实现迭代器(Iterator)的接口。
实现迭代器的接口,需要在这个对象上实现[Symbol,iterator]属性方法。

var obj = {
  0: 'abc',
  1: 'def',
  //实现[Symbol.iterator]属性方法
  [Symbol.iterator]:function() {
    const self = this
    let index = 0
    return {
      next: function(){//实现next()
        if(index<2){
          return {//遍历中
            value: self[index++],
            done:false//表示遍历没有结束,done设置为fasle
          }
        }else{
          return {
            value: undefined,//结束后,返回undefined
            done: true//表示遍历结束,done设置为true
          }
        }
      }
    }
  }
}
for(var val of obj){
  console.log(val)
}

此时正确的遍历了obj,[Symbol.iterator]属性函数体,返回了next方法,next方法中遍历了此obj的属性对象,并返回字面量对象{value:xxx,done:xxx}。遍历过程中value表示对应属性值,且done设置false;当遍历结束后,value返回undefined,且done设置为true。

var it = obj[Symbol.iterator]()
console.log(it.next())//{value: 'abc', done: false}
console.log(it.next())//{value: 'def', done: false}
console.log(it.next())//{value: undefined, done: true}

这就是for-of的原理,每次遍历都会调用对象的[Symbol.iterator]属性的next方法,当返回{value: undefined,done: true}后,表示遍历结束。随意任何对象要变成可遍历对象,只需要实现[Symbol.iterator]属性方法,定义其中的next方法即可。

3、break,continue

for-of对于for-in的优点就是它支持这些语句。

let arr = 'abc'
for(var char of arr){
  console.log(char) //'a'
  break
}

仅输出了'a'就跳出的循环。
我们将上面的obj修改一下,使其支持这些语句

var obj = {
  0: 'abc',
  1: 'def',
  //实现[Symbol.iterator]属性方法
  [Symbol.iterator]:function() {
    const self = this
    let index = 0
    return {
      next: function(){// 实现next()
        if(index<2){
          return {//遍历中
            value: self[index++],
            done:false//表示遍历没有结束,done设置为fasle
          }
        }else{
          return {
            value: undefined,//结束后,返回undefined
            done: true//表示遍历结束,done设置为true
          }
        }
      },
      return: function(){//增加return,支持break,continue
        return {done:false}
      }
    }
  }
}
for(var val of obj){
  console.log(val)
  break
}

相关文章

网友评论

      本文标题:Iterator详解

      本文链接:https://www.haomeiwen.com/subject/hppmxqtx.html