zoukankan      html  css  js  c++  java
  • Iterator接口(遍历器)和for/of循环

    在javascript中表示“集合”的数据结构,主要有Array,Object,Map,Set。

    Iterator(遍历器)接口是为各种不同的数据结构提供了统一的访问机制。任何数据结构具有Iterator接口,就可以完成遍历操作(依次排序进行遍历)。

    Iterator遍历的过程:

    创建一个指针对象,指向数据结构的初始位置——调用指针对象的next方法,指向数据结构成员——不断调用next方法,直到指向数据结构的结束位置。

    var it = makeIterator(['a','b']);
    
    function makeIterator(array){
       var nextIndex = 0;
       return{
           next:function(){
               return nextIndex < array.length ? 
               {value:array[nextIndex++],done:false} : 
               {value:undefined,done:true}
           }
       }
    }
    
    it.next() 

    默认的Iterator接口
    Iterator借口的目的在于:为所有数据结构,提供统一的访问机制。即用for/of循环,当使用for/of进行遍历的时候,该循环会自动去寻找Iterator接口。

    默认的Iterator接口部署在数据结构的Symbol.iterator属性,一个数据结构只要有Symbol.Iterator属性,就是“可遍历的”,Symbol.iterator属性本身是一个函数,执行这个函数,返回 一个遍历器。

    ES6中原生具备Iterator接口的数据结构如下:

    Array  Map  Set  String  TypedArray  函数的arguments对象  NodeList对象

    let arr = [1,2,3,4,5]
    let iter = arr[Symbol.iterator]();
    iter.next()

    一个对象具备Iterator接口,必须在Symbol.iterator的属性上部署遍历器生成方法(原型链上的对象具有该方法也可)

    只要某个数据结构部署了Iterator接口,就可以使用拓展运算符将其转化为数组。

    let arr = [...iterator];
    
    var str = 'hello';
    [...str]  //["h", "e", "l", "l", "o"]

    yield* 后面跟的是一个可遍历的结构,它会调用该结构的遍历器接口。

    let generator = function* (){
        yield 1;
        yield* [2,3,4];
        yield 5;
    }
    var it = generator();
    it.next();  //{value: 1, done: false}
    it.next()   //{value: 2, done: false}
    it.next()   //{value: 3, done: false}
    it.next()   //{value: 4, done: false}
    it.next()   //{value: 5, done: false}
    it.next()   //{value: undefined, done: true}

    数组的遍历会调用遍历器接口,所以任何接受数组作为参数的场合,其实都调用了Iterator接口,如下:

    for/of    Array.from()   Map()    Set()   WeakMap()   WeakSet()  Promise.all()  Promise.rece()

    1,字符串的Iterator接口

    var str = 'hi';
    typeof str[Symbol.iterator]    //'function'
    
    var a = str[Symbol.iterator]();
    a.next()   //{value: "h", done: false}
    a.next()   //{value: "i", done: false}
    
    [...str]     //["h", "i"]

    以前字符串转化为数组:str.split(""),ES6中可以使用Iterator进行遍历加入数组中,相当简洁。

     这里写一个能用for/of进行遍历对象的方法键值的方法:

    function* entries(obj) {
      for (let key of Object.keys(obj)) {
        yield [key, obj[key]];
      }
    }
    
    for (let [key, value] of entries(obj)) {
      console.log(key, '->', value);
    }
    // a -> 1
    // b -> 2
    // c -> 3

    其他遍历方法的比较:

    forEach内部写break命令不奏效,会报错,return语句是可以写的。

    for/in是用来遍历对象的键名,数组的索引,主要适用于遍历对象。

    for/of主要是用来遍历数组的值,可以搭配break,continue,return等,提供了遍历所有数据结构的统一操作接口。

  • 相关阅读:
    最小费用最大流
    bzoj1070[SCOI2007]修车
    bzoj1877[SDOI2009]晨跑
    bzoj2879[NOI2012]美食节
    bzoj1834[ZJOI2010]网络扩容
    Tic-Tac-Toe-(暴力模拟)
    javascript慕课入门
    hdu2586-How far away ?-(最近公共祖先-Tarjan离线算法)
    CSS初识盒子
    CF1047C-Enlarge GCD-(欧拉筛+gcd+唯一分解定理)
  • 原文地址:https://www.cnblogs.com/tangjiao/p/9046429.html
Copyright © 2011-2022 走看看