zoukankan      html  css  js  c++  java
  • for in和for of的区别

    一、for in和for of

    for in

    for...in语句以任意顺序遍历一个对象的除Symbol以外的可枚举属性。

    for in遍历数组的问题

    1. index索引并不是一个数字,而是一个String,不能直接进行几何运算,容易误操作为字符串计算。
    2. 遍历顺序有可能不是按照实际数组的内部顺序。
    3. 使用for in会遍历数组所有的可枚举属性,包括原型。比如下面示例中的原型方法method和name属性。
      所以for in更适合遍历对象,不要使用for in遍历数组。

    例:

    Array.prototype.method=function(){
      console.log(this.length);
    }
    var myArray=[1,2,4,5,6,7]
    myArray.name="数组"
    for (var index in myArray) {
      console.log(myArray[index]);
    }
    // 1,2,4,5,6,7,"name",f(){console.log(this.length)}
    

    使用for in遍历对象

    通常用for in来遍历对象的键名

    Object.prototype.method=function(){
      console.log(this);
    }
    var myObject={
      a:1,
      b:2,
      c:3
    }
    for (var key in myObject) {
      console.log(key);
    }
    //a,b,c,method
    

    for in 可以遍历到myObject的原型方法method,如果不想遍历原型方法和属性的话,可以在循环内部判断一下,hasOwnPropery方法可以判断某属性是否是该对象的实例属性

    for (var key in myObject) {
      if(myObject.hasOwnProperty(key)){
        console.log(key);
      }
    }
    

    同样可以通过ES5的Object.keys(myObject)获取对象的实例属性组成的数组,不包括原型方法和属性

    Object.prototype.method=function(){
      console.log(this);
    }
    var myObject={
      a:1,
      b:2,
      c:3
    }
    console.log(Object.keys(myObject));
    //["a", "b", "c"]
    

    for of

    那么除了使用for循环,如何更简单的正确的遍历数组达到我们的期望呢(即不遍历method和name),ES6中的for of更胜一筹。

    Array.prototype.method=function(){
      console.log(this.length);
    }
    var myArray=[1,2,4,5,6,7]
    myArray.name="数组";
    for (var value of myArray) {
      console.log(value);
    }
    //1,2,4,5,6,7
    

    记住,for in遍历的是数组的索引(即键名),而for of遍历的是数组元素值。
    for of遍历的只是数组内的元素,而不包括数组的原型属性method和索引name。

    for of的执行步骤
    for of循环首先调用集合的Symbol.iterator方法,紧接着返回一个新的迭代器对象。迭代器对象可以是任意具有.next()方法的对象;for-of循环将重复调用这个方法,每次循环调用一次。举个例子,这段代码是我能想出来的最简单的迭代器:

    var zeroesForeverIterator = {
      [Symbol.iterator]: function () {
        return this;
      },
      next: function () {
        return {done: false, value: 0};
     }
    };
    

    总结

    • 推荐在循环对象属性的时候,使用for...in,在遍历数组的时候的时候使用for...of。

    • for...in循环出的是key,for...of循环出的是value

    • 注意,for...of是ES6新引入的特性。修复了ES5引入的for...in的不足。

    • for of循环可以使用的范围包括数组、Set 和 Map 结构、某些类似数组的对象(比如arguments对象、DOM NodeList 对象)、 Generator 对象,以及字符串。

    • for...of不能循环普通的对象,因为没有迭代器对象。但如果你想迭代一个对象的属性,你可以用for in循环(这也是它的本职工作)或与内建的 Object.keys() 方法搭配,示例如下。

    var student={
      name:'wujunchuan',
      age:22,
      locate:{
        country:'china',
        city:'xiamen',
        school:'XMUT'
      }
    }
    for(var key of Object.keys(student)){
      //使用Object.keys()方法获取对象key的数组
      console.log(key+": "+student[key]);
    }
    //但这还不如直接使用 for in 简单快捷
    

    补充

    for in循环由于历史遗留问题,它遍历的实际上是对象的属性名称。一个Array数组实际上也是一个对象,它的每个元素的索引被视为一个属性。

    当我们手动给Array对象添加了额外的属性后,for in循环将带来意想不到的意外效果:

    var a = ['A', 'B', 'C'];
    a.name = 'Hello';
    for (var x in a) {
      console.log(x); // '0', '1', '2', 'name'
    }
    

    for in循环将把name包括在内,但Array的length属性却不包括在内。

    for of循环则完全修复了这些问题,它只循环集合本身的元素:

    var a = ['A', 'B', 'C'];
    a.name = 'Hello';
    for (var x of a) {
      console.log(x); // 'A', 'B', 'C'
    }
    

    这就是为什么要引入新的for ... of循环。

    然而,更好的方式是直接使用iterable内置的forEach方法,它接收一个函数,每次迭代就自动回调该函数。

    var a = ['A', 'B', 'C'];
    a.name = 'Hello';
    a.forEach((ele,i)=>{
      console.log(ele); // 'A', 'B', 'C'
    })
    
  • 相关阅读:
    数据库连接池大小
    java的关闭钩子(Shutdown Hook)
    为线程池中的每个线程设置UncaughtExceptionHandler
    java 线程的interrupt和sleep、wait
    中断
    NIO
    VMware 安装 VMware Tools 工具
    php 雪花算法
    python 执行系统文件
    php curl 获取响应头
  • 原文地址:https://www.cnblogs.com/ZerlinM/p/13589236.html
Copyright © 2011-2022 走看看