• ES6知识点整理之----Iterator(遍历器)----for...of循环


    一个数据结构只要部署了Symbol.iterator属性,就被视为具有 iterator 接口,就可以用for...of循环遍历它的成员。

    for...of循环内部调用的是数据结构的Symbol.iterator方法。

    for...of循环可以使用的范围:

    • 数组
    • Set、Map结构
    • 某些类似数组的对象(比如arguments对象、DOM NodeList 对象)
    • Generator 对象
    • 字符串

    1、数组

    const arr = ['red', 'green', 'blue'];
    
    for(let v of arr) {
      console.log(v); // red green blue
    }
    
    const obj = {};
    obj[Symbol.iterator] = arr[Symbol.iterator].bind(arr);
    
    for(let v of obj) {
      console.log(v); // red green blue
    }

    for...of循环可以代替数组实例的forEach方法。

    const arr = ['red', 'green', 'blue'];
    
    arr.forEach(function (element, index) {
      console.log(element); // red green blue
      console.log(index);   // 0 1 2
    });

    JavaScript 原有的for...in循环,只能获得对象的键名,不能直接获取键值。ES6 提供for...of循环,允许遍历获得键值。

    var arr = ['a', 'b', 'c', 'd'];
    
    for (let a in arr) {
      console.log(a); // 0 1 2 3
    }
    
    for (let a of arr) {
      console.log(a); // a b c d
    }

    for...of循环调用遍历器接口,数组的遍历器接口只返回具有数字索引的属性。这一点跟for...in循环也不一样。

    let arr = [3, 5, 7];
    arr.foo = 'hello';
    
    for (let i in arr) {
      console.log(i); // "0", "1", "2", "foo"
    }
    
    for (let i of arr) {
      console.log(i); //  "3", "5", "7"
    }

    2、Set 和 Map 结构

    var engines = new Set(["Gecko", "Trident", "Webkit", "Webkit"]);
    for (var e of engines) {
      console.log(e);
    }
    // Gecko
    // Trident
    // Webkit
    
    var es6 = new Map();
    es6.set("edition", 6);
    es6.set("committee", "TC39");
    es6.set("standard", "ECMA-262");
    for (var [name, value] of es6) {
      console.log(name + ": " + value);
    }
    // edition: 6
    // committee: TC39
    // standard: ECMA-262
    • 遍历的顺序是按照各个成员被添加进数据结构的顺序
    • Set 结构遍历时,返回的是一个值,而 Map 结构遍历时,返回的是一个数组

    3、计算生成的数据结构

    有些数据结构是在现有数据结构的基础上,计算生成的。如:

    • entries() 返回一个遍历器对象,用来遍历[键名, 键值]组成的数组。对于数组,键名就是索引值;对于 Set,键名与键值相同。Map 结构的 Iterator 接口,默认就是调用entries方法。
    • keys() 返回一个遍历器对象,用来遍历所有的键名。
    • values() 返回一个遍历器对象,用来遍历所有的键值。
    let arr = ['a', 'b', 'c'];
    for (let pair of arr.entries()) {
      console.log(pair);
    }
    // [0, 'a']
    // [1, 'b']
    // [2, 'c']

    4、类似数组的对象

    // 字符串
    let str = "hello";
    
    for (let s of str) {
      console.log(s); // h e l l o
    }
    
    // DOM NodeList对象
    let paras = document.querySelectorAll("p");
    
    for (let p of paras) {
      p.classList.add("test");
    }
    
    // arguments对象
    function printArgs() {
      for (let x of arguments) {
        console.log(x);
      }
    }
    printArgs('a', 'b');
    // 'a'
    // 'b'

    使用Array.from方法将其转为数组

    let arrayLike = { length: 2, 0: 'a', 1: 'b' };
    
    // 报错
    for (let x of arrayLike) {
      console.log(x);
    }
    
    // 正确
    for (let x of Array.from(arrayLike)) {
      console.log(x);
    }

    5、对象

    对于普通的对象,for...of结构不能直接使用,会报错,必须部署了 Iterator 接口后才能使用。但是,这样情况下,for...in循环依然可以用来遍历键名。

    let es6 = {
      edition: 6,
      committee: "TC39",
      standard: "ECMA-262"
    };
    
    for (let e in es6) {
      console.log(e);
    }
    // edition
    // committee
    // standard
    
    for (let e of es6) {
      console.log(e);
    }
    // TypeError: es6[Symbol.iterator] is not a function

    解决方法:

    a、使用Object.keys方法将对象的键名生成一个数组,然后遍历这个数组。

    for (var key of Object.keys(someObject)) {
      console.log(key + ': ' + someObject[key]);
    }

    b、使用 Generator 函数将对象重新包装一下。

    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

    与其他遍历语法的比较

    • 最原始的for循环
    • forEach方法
    • for...in循环
    • for...of循环
    //原始的for循环
    //缺点:写法比较麻烦
    for (var index = 0; index < myArray.length; index++) { console.log(myArray[index]); } //forEach
    //缺点:无法中途跳出forEach循环,break或return都不能奏效
    myArray.forEach(function (value) { console.log(value); }); //for...in
    //缺点:
    //1、
    数组的键名是数字,但是for...in循环是以字符串作为键名“0”、“1”、“2”等等。
    //2、for...in循环不仅遍历数字键名,还会遍历手动添加的其他键,甚至包括原型链上的键。
    //3、某些情况下,for...in循环会以任意顺序遍历键名
    for (var index in myArray) { console.log(myArray[index]); } //for...of
    //优点:
    //1、
    有着同for...in一样的简洁语法,但是没有for...in那些缺点。
    //2、不同于forEach方法,它可以与breakcontinuereturn配合使用。
    //3、提供了遍历所有数据结构的统一操作接口。 for (let value of myArray) { console.log(value); }
  • 相关阅读:
    Java学习二十九天
    Java学习二十八天
    47. Permutations II 全排列可重复版本
    46. Permutations 全排列,无重复
    subset ii 子集 有重复元素
    339. Nested List Weight Sum 339.嵌套列表权重总和
    251. Flatten 2D Vector 平铺二维矩阵
    217. Contains Duplicate数组重复元素
    209. Minimum Size Subarray Sum 结果大于等于目标的最小长度数组
    438. Find All Anagrams in a String 查找字符串中的所有Anagrams
  • 原文地址:https://www.cnblogs.com/adhehe/p/9680190.html
Copyright © 2020-2023  润新知