美文网首页
15Iterator和for方法

15Iterator和for方法

作者: 我_巨可爱 | 来源:发表于2017-10-30 17:02 被阅读0次

    Iterator 概念

    遍历器本质上就是一个指针对象

    1. 只有布置了遍历器接口,才可遍历。遍历器接口是[Symbol.iterator]

    Iterator 作用

    1. 为各种数据结构提供一个统一的访问接口
    2. 使得数据结构的成员能够按照某种次序排序
    3. for of提供接口

    Iterator 遍历过程

    • 创建一个指针对象,指向当前数据结构的起始位置
    • 第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。返回数据结构的当前成员,具体就是一个包含valuedone的对象。
    • 不断调用指针对象的next方法,直到它指向数据结构的结束位置

    默认 Iterator 接口

    注意,对象没有Iterator接口

    1. 原生具备 Iterator 接口的数据结构如下
    • Array
    • Set,类似数组,但是成员的值是唯一的
    • Map,类似对象,但是"键"的范围不限于字符串,各种类型的值都可以当作键
    • String
    • TypedArray
    • 函数的 arguments 对象
    • NodeList 对象(类数组对象)
    1. object 不具备原生Iterator接口,需要在[Symbol.iterator]上布置。生成的每项形式为[key,val]
    // 为一个类数组对象布置 Iterator 接口
    let obj = {
      0:'y',
      1: 'f',
      length: 2,
      [Symbol.iterator]() {
        const self = this;
        let index = 0;
        return {
          next() {
            if (index < self.length) {
              return {
                value: [index,self[index++]],
                done: false
              };
            } else {
              return { value: undefined, done: true };
            }
          }
        };
      }
    };
    // 布置到 Object 上
    Object.prototype[Symbol.iterator] = function () {
    }
    

    通过遍历器实现指针结构的例子

    // 指针结构
    // 数据结构
    function Obj(value) {
        this.value =value;
        this.next = null;
    }
    // 布置遍历接口
    Obj.prototype[Symbol.iterator] = function () {
        var iterator = { next: next };
    
        var current = this;
        function next() {
            if (current) {
                val value = current.value;
                current = current.next;
                return { done: false, value: value }
            } else {
                return { done: true }
            }
        }
    
        return iterator;
    }
    var one = new Obj(1);
    var two = new Obj(2);
    var three = new Obj(3);
    
    one.next = two;
    two.next = three;
    
    for (var i of one) {
        console.log(i);
    }
    

    生成 Iterator 方式

    var arr = [1,2,3];
    var iterator = arr[Symbol.iterator]();
    

    默认调用Iterator接口的场合

    1. 解构赋值
    • 对数组和 Set 解构进行解构赋值时
    1. 扩展运算符
    • ...使用扩展运算符
    1. yield*
    2. 其他场合
    • for of
    • Array.from()
    • Map()
    • Set()
    • WeakMap()
    • WeakSet()
    • Promise.all()
    • Promise.race()
    // 解构赋值
    let set = new Set().add('a').add('b').add('c');
    let [x,y] = set;
    

    字符串的 Iterator 接口

    // 使用字符串原生的遍历器接口
    var str = 'hi';
    var iterator = str[Symbol.iterator]();
    
    iterator.next()  // { value: "h", done: false }
    iterator.next()  // { value: "i", done: false }
    iterator.next()  // { value: undefined, done: true }
    

    遍历器对象的return(),throw()

    for of中使用break或者continue提前退出,会调用return方法

    //遍历器,必须返回一个包含next方法的对象
    // 可选的返回一个包含了throw方法和return方法的对象
    function ite() {
        return {
            next() {
                return {done: false}
            },
            return() {
                file.close();
                return { done: true }
            }
        }
    }
    // throw 方法不常用
    

    for of循环

    数组

    // for in 获取的是键名,包含了数组的索引和属性,甚至原型上的属性
    var arr = [7,9,0];
    arr.foo = 'bar';
    for (let i in arr) {
        console.log(i);  // '0','1','2','foo'
    }
    // for of 获取的是数组每项的值
    for (let i of arr) {
        console.log(i);  // '7','9','0'
    }
    

    Set 和 Map 解构

    计算生成的数据结构

    数组,Set,Map部署了下面三个方法,这些方法都返回遍历器对象

    1. entries()
    2. keys()
    3. values()

    类似数组的对象

    并不是所有类似数组的对象都有 Iterator 接口,可以使用Array.from将其转化为数组,再使用for of方法

    对象

    普通对象,不能直接使用for of,会报错。解决方法:

    1. 使用Object.keys()生成一个由对象属性值组成的数组,再使用for of
    2. 另一个方法使用Generator将对象包装一下
    3. 可以在对象实例上直接布置[Symbol.iterator],也可以在对象原型链上布置[Symbol.iterator]。部署类数组对象的[Symbol.iterator]和普通对象的[Symbol.iterator]方法不同
    // 使用 Generator 将对象包装一下
    function* entries(obj) {
        // 使用的是Object.keys而不是for in 循环
      for (let key of Object.keys(obj)) {
        yield [key, obj[key]];
      }
    }
    
    for (let [key, value] of entries(obj)) {
      console.log(key, '->', value);
    }
    

    相关文章

      网友评论

          本文标题:15Iterator和for方法

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