【ECMAScript 5_6_7】11、ES6——Itetetator遍历器

概念:

iterator是一种接口机制,为各种不同的数据结构提供统一的访问机制

作用:

1、为各种数据结构,提供一个统一的、简便的访问接口;
2、使得数据结构的成员能够按某种次序排列
3、ES6创造了一种新的遍历命令for...of循环,Iterator接口主要供for...of消费

工作原理:

- 创建一个指针对象(遍历器对象),指向数据结构的起始位置。
- 第一次调用next方法,指针自动指向数据结构的第一个成员
- 接下来不断调用next方法,指针会一直往后移动,直到指向最后一个成员
- 每调用next方法返回的是一个包含value和done的对象,{value: 当前成员的值,done: 布尔值}
  * value表示当前成员的值,done对应的布尔值表示当前的数据的结构是否遍历结束,在遍历过程中done始终是false
  * 当遍历结束的时候返回的value值是undefined,done值为true

原生具备iterator接口的数据(可用for of遍历):

1、Array
2、arguments
3、set容器
4、map容器
5、String
。。。
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Iterator遍历器</title>
</head>
<body>
  <script type="text/javascript">

    //模拟一个Iterator接口
    function myIterator(arr) {
      let index = 0  // 记录指针的位置
      return {  // 这个对象的返回值就是一个对象指针
        next:function () {  // 在对象指针当中有一个next这样的方法对应一个函数
          return index<arr.length ? {value:arr[index++],done:false} : {value:undefined,done:true}  // 判断条件决定done的返回值
        }
      }
    }
    let arr = [1,40,'abc',true]
    const it = myIterator(arr)  // 这里将闭包返回值赋给一个常量,否则闭包会被回收,剩下的遍历又重新开始
    console.log(it.next())  // {value: 1, done: false}
    console.log(it.next())  // {value: 40, done: false}
    console.log(it.next())  // {value: "abc", done: false}
    console.log(it.next())  // {value: true, done: false}
    console.log(it.next())  // {value: undefined, done: true}

    console.log('----------------------')
    // ES6已经设计好Iterator接口部署到指定的数据类型上,可以用for of去循环遍历
    // 数组、字符串、arguments、set容器、map容器
    for(let i of arr){
      console.log(i)  // 1 40 abc true
    }
    let str = 'ondean'
    for(let i of str){
      console.log(i)  // o n e d e a n
    }
    function fun() {
      for(let i of arguments){
        console.log(i)  // 100 200 false 'china'
      }
    }
    fun(100,200,false,'china')

    console.log('----------------------')
    /*
    底层实现原理:
      对象的Symbol.iterator属性,指向该对象的默认遍历器方法,等同于是在指定的数据内结构部署Iterator接口
      当使用for of去遍历某一个数据结构时,首先去找Symbol.iterator,找到了就去遍历,没有找到就不能遍历xxx is not iterator
    */
    /*let obj = {
      [Symbol.iterator]: function () {
        let index = 0
        return {  // 这个对象的返回值就是一个对象指针
          next:function () {  // 在对象指针当中有一个next这样的方法对应一个函数
            return index<this.length ? {value:this[index++],done:false} : {value:undefined,done:true}  // 判断条件决定done的返回值
          }
        }
      }
    }*/
    //如下:一个对象如果要具备可被for...of循环调用的Iterator接口,就必须在Symbol.iterator的属性上部署遍历器生成方法(原型链上的对象具有该方法也可)
    class RangeIterator {
      constructor(start, stop) {
        this.value = start;
        this.stop = stop;
      }
      [Symbol.iterator]() { return this; }
      next() {
        var value = this.value;
        if (value < this.stop) {
          this.value++;
          return {done: false, value: value};
        }
        return {done: true, value: undefined};
      }
    }
    function range(start, stop) {
      return new RangeIterator(start, stop);
    }
    for (var value of range(0, 3)) {
      console.log(value); // 0, 1, 2
    }

    console.log('----------------------')
    //使用三点运算符、解构赋值默认原理是去调用Iterator接口
    let arr2 = [1,6]
    let arr3 = [2,3,4,5]
    arr2 = [1,...arr3,6]
    console.log(arr2)  // (6) [1, 2, 3, 4, 5, 6]
    let [x,y] = arr2
    console.log(x,y)  // 1 2

  </script>
</body>
</html>

猜你喜欢

转载自blog.csdn.net/edc3001/article/details/87943001