zoukankan      html  css  js  c++  java
  • 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); }
  • 相关阅读:
    linux的常用命令--pwd命令【持续补充ing】
    linux的常用命令--cp命令【持续补充ing】
    linux的常用命令--mkdir【持续补充ing】
    linux的常用命令--su篇【持续补充ing】
    linux的常用命令--ls篇【持续补充ing】
    linux的常用命令--cd篇【持续补充ing】
    【SQL Server 2008数据库基础篇】常用关键字、数据类型和常用语法
    SpingBoot之多Profile文件
    SpringBoot之YAML
    SpringBoot之HelloWorld仔细分析
  • 原文地址:https://www.cnblogs.com/adhehe/p/9680190.html
Copyright © 2011-2022 走看看