美文网首页
浅谈for in与for of的使用对比

浅谈for in与for of的使用对比

作者: 小碗碗碗碗 | 来源:发表于2020-06-09 21:22 被阅读0次

    一、for...in

    1、枚举对象

    var obj = {
      a: 1,
      b: [],
      c: function () {}
    };
    for (var key in obj) {
       console.log(key);
    }
    // 结果是:
    // a
    // b
    // c
    

    2、枚举数组
    for..in不仅可以枚举数组自身,

    var arr = [3, 5, 7];
    for (var i in arr) {
       console.log(i, arr[i]);
    }
    // 结果是:
    // 0 3
    // 1 5
    // 2 7
    

    还能枚举数组的原型对象以及数组对象本身属性值。

    Object.prototype.objCustom = function() {}; 
    Array.prototype.arrCustom = function() {};
    
    var arr = [3, 5, 7];
    arr.foo = 'hello';
    
    for (var i in arr) {
       console.log(i);
    }
    // 结果是:
    // 0
    // 1
    // 2
    // foo
    // arrCustom
    // objCustom
    

    在实际工作开发中,原型对象很可能是不需要的,不需要全部枚举出来。
    此时,可以使用JS的内置对象方法hasOwnProperty来避免这个问题。

    Object.prototype.objCustom = function() {}; 
    Array.prototype.arrCustom = function() {};
    
    var arr = [3, 5, 7];
    arr.foo = 'hello';
    
    for (var i in arr) {
       if (arr.hasOwnProperty(i)) {
        console.log(i);
      }
    }
    // 结果是:
    // 0
    // 1
    // 2
    // foo
    

    但是用这个办法,依然无法摆脱数组本身的属性。
    此时,可以使用数组方法forEach来解决这个问题。

    Object.prototype.objCustom = function() {}; 
    Array.prototype.arrCustom = function() {};
    
    var arr = [3, 5, 7];
    arr.foo = 'hello';
    
    arr.forEach(function (value, i) {
      console.log(i);
    });
    // 结果是:
    // 0
    // 1
    // 2
    

    3、枚举字符串
    for in的枚举字符串是在IE9+之后才支持的。

    let str = 'boo';
    
    for (let value in str) {
      console.log(value, str[value]);
    }
    // 结果是:
    // "b"
    // "o"
    // "o"
    // d ƒ (e){return this||e||""}
    // defaultMessage ƒ (e){return this||e||""}
    

    二、for...of

    1、枚举对象

    var obj = {
      a: 1,
      b: [],
      c: function () {}
    };
    for (var key of obj) {
       console.log(key);
    }
    // 出错:
    // Uncaught TypeError: obj is not iterable
    

    2、迭代数组
    for..of对数组的枚举是直接输出了数组的值,无法获取数组的索引。
    key

    var arr = [3, 5, 7];
    for (var i of arr) {
       console.log(i);
    }
    // 结果是:
    // 3
    // 5
    // 7
    

    3、迭代字符串

    let str = 'boo';
    
    for (let value of str) {
      console.log(value);
    }
    // 结果是:
    // "b"
    // "o"
    // "o"
    

    4、迭代arguments类数组对象

    (function() {
      for (let argument of arguments) {
        console.log(argument);
      }
    })(1, 2, 3);
    // 结果是:
    // 1
    // 2
    // 3
    

    5、迭代NodeList这类DOM集合
    for of迭代NodeList这类DOM集合时,无需[].slice.call(),也不需要Array.from()进行数组转化。

    let elements = document.querySelectorAll('body');
    
    for (let element of elements) {
      console.log(element.tagName);
    }
    // 结果是:
    // "BODY"
    

    6、迭代类型数组

    let typeArr = new Uint8Array([0x00, 0xff]);
    
    for (let value of typeArr) {
      console.log(value);
    }
    // 结果是:
    // 0
    // 255
    

    7、迭代Map和Set

    let mapData = new Map([['a', 1], ['b', 2], ['c', 3]]);
    for (let [key, value] of mapData) {
      console.log(value);
    }
    // 结果是:
    // 1
    // 2
    // 3
    
    
    let setData = new Set([1, 1, 2, 2, 3, 3]);
    for (let value of setData) {
      console.log(value);
    }
    // 结果是:
    // 1
    // 2
    // 3
    

    三、总结

    1、for in与for of相比
    对于纯对象的遍历,使用for..in更合适;
    对于数组遍历,如果不需要知道索引,for..of迭代更合适,因为还可以中断;
    对于数组遍历,如果需要知道索引,则forEach()更合适;
    对于其他字符串、类数组、类型数组的迭代,虽然for..in也有这方面能力,使用for..of更方便;
    对于兼容性,果断使用for..in,因为for..of是S6新特性,IE浏览器不支持。(微笑)
    2、forEach与for of相比
    两者都可以遍历数组,但forEach遍历数组时无法break或return false中断遍历,而这一点for of可以做到。

    var arr = [3, 5, 7];
    
    arr.forEach(function (value) {
      console.log(value);
      if (value == 5) {
        return false;
      }
    });
    // 结果是:
    // 3
    // 5
    // 7
    
    var arr = [3, 5, 7];
    
    for (let value of arr) {
      console.log(value);
      if (value == 5) {
        break;
      }
    }
    // 结果是:
    // 3
    // 5
    

    枚举与迭代的区别
    枚举:指调用一个枚举函数、一次性列举出集合中的元素,通常需要指定一个触发器函数作为参数。
    迭代:迭代函数通常用于for...in语句中,创建一个迭代器,用以遍历集合成员。

    1、枚举一般指使用回调触发器机制来遍历对象;而迭代一般是使用用for...in语句来循环迭代对象。
    2、枚举是一次性列举出集合中的元素;迭代函数不是一次性列举出所有元素,他是在一个循环中每次迭代出集合中的一个成员
    3、枚举可以通过返回值来被动退出遍历过程;而迭代随时可以用break语句来主动中断遍历过程,在控制上更自由一些。
    4、这就好象演出,枚举是一次性全站台上;而迭代是一个一个的轮流上台,随时可以叫停。
    5、迭代是广度遍历,通常在同一深度遍历集合对象;而枚举是枚举可以通过递归深度遍历集合。

    相关文章

      网友评论

          本文标题:浅谈for in与for of的使用对比

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