zoukankan      html  css  js  c++  java
  • for、for-in、for-of、forEach的区别

    总结

    for..of适用遍历数/数组对象/字符串/map/set等拥有迭代器对象的集合.但是不能遍历对象,因为没有迭代器对象.与forEach()不同的是,它可以正确响应break、continue和return语句。

    for-of循环不支持普通对象,但如果你想迭代一个对象的属性,你可以用for-in循环(这也是它的本职工作)或内建的Object.keys()方法。

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

    forEach(value,index,Array)不能同时遍历多个集合,在遍历的时候无法修改和删除集合数据,方法不能使用break,continue语句跳出循环,或者使用return从函数体返回,对于空数组不会执行回调函数。

    forEach与for当循环遍历为空的数组时,forEach会跳过为空的值,for不会跳过为空的数据,会直接显示undefined。两者都能识别出NULL。

    forEach() 被调用时,不会改变原数组,也就是调用它的数组(尽管 callback 函数在被调用时可能会改变原数组)。


    具体区别如下:

    FOR

    var arrList = [1,2,3,4,5,6]
    for(var i = 0;i < arrList.length ; i++){
        console.log(arrList[i]);
    }
    

    FOR-IN

    语法

    for (variable in object)
      statement
    
    • variable

      在每次迭代时,variable会被赋值为不同的属性名。

    • object

      非Symbol类型的可枚举属性被迭代的对象。

    描述

    for...in 循环只遍历可枚举属性(包括它的原型链上的可枚举属性)。ArrayObject使用内置构造函数所创建的对象都会继承自Object.prototypeString.prototype的不可枚举属性,例如 StringindexOf() 方法或 ObjecttoString()方法。循环将遍历对象本身的所有可枚举属性,以及对象从其构造函数原型中继承的属性(更接近原型链中对象的属性覆盖原型属性)。

    举例

    /*
    	FOR..IN语句遍历数组
    */
    Array.prototype.method=function(){
      console.log(this.length);
    }
    var myArray=[1,2,4]
    myArray.name="数组"
    for (var index in myArray) {
      console.log(myArray[index]);
    }
    /*
    	输出结果顺序不唯一。输出的结果包含如下:
    	1 
    	2 
    	4 
    	数组
    	ƒ (){
      	console.log(this.length);
    	}
    */
    
    /*
    	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
    	
    	1- for in 可以遍历到myObject的原型方法method,如果不想遍历原型方法和属性的话,可以在循环内部判断一		下,hasOwnPropery方法可以判断某属性是否是该对象的实例属性.
    	2- 通过ES5的Object.keys(myObject)获取对象的实例属性组成的数组,不包括原型方法和属性.
    */
    
    for (var key in myObject) {
      if(myObject.hasOwnProperty(key)){
        console.log(key);
      }
    }
    /*
    	输出结果顺序不唯一。输出的结果包含如下:
    	a 
    	b
    	c 
    */
    
    

    注意事项

    • FOR..IN语句遍历的是索引index(键名)为字符串型数字,不能直接进行几何运算。

    • 遍历顺序有可能不是按照实际数组的内部顺序。FOR..IN语句以任意顺序遍历一个对象的除Symbol以外的可枚举属性。

    • 使用for in会遍历数组所有的可枚举属性,包括原型。例如上述案例的原型方法method和name属性,所以for in更适合遍历对象,不要使用for in遍历数组。

    删除,添加或者修改属性

    for...in 循环以任意序迭代一个对象的属性(请参阅delete运算符,了解为什么不能依赖于迭代的表面有序性,至少在跨浏览器设置中)。如果一个属性在一次迭代中被修改,在稍后被访问,其在循环中的值是其在稍后时间的值。一个在被访问之前已经被删除的属性将不会在之后被访问。在迭代进行时被添加到对象的属性,可能在之后的迭代被访问,也可能被忽略。

    通常,在迭代过程中最好不要在对象上进行添加、修改或者删除属性的操作,除非是对当前正在被访问的属性。这里并不保证是否一个被添加的属性在迭代过程中会被访问到,不保证一个修改后的属性(除非是正在被访问的)会在修改前或者修改后被访问,不保证一个被删除的属性将会在它被删除之前被访问。

    FOR-OF

    for...of语句可迭代对象(包括 ArrayMapSetStringTypedArrayarguments 对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句。不建议遍历原有的原生对象。

    语法

    for (variable of iterable) {
        //statements
    }
    
    • variable

      在每次迭代中,将不同属性的值分配给变量。

    • iterable

      被迭代枚举其属性的对象。

    示例

    /*
    	FOR..OF语句遍历数组
    */
    var myArray=[1,2,4,5,6,7,8]
    for (var index of myArray) {
      console.log(index);
    }
    /*
    	输出结果顺序唯一。输出的结果如下:
    	1
    	2
    	4
    	5
    	6
    	7
    	8
    */
    

    FOREACH

    语法

    arr.forEach(callback(currentValue [, index [, array]])[, thisArg]);
    

    参数

    • callback

      为数组中每个元素执行的函数,该函数接收三个参数:currentValue数组中正在处理的当前元素。index 可选数组中正在处理的当前元素的索引。array 可选forEach() 方法正在操作的数组。

    • thisArg 可选

      可选参数。当执行回调函数 callback 时,用作 this 的值。

    返回值

    undefined

    描述

    forEach() 方法按升序为数组中含有效值的每一项执行一次 callback 函数,那些已删除或者未初始化的项将被跳过(例如在稀疏数组上)。

    举例

    /*
    	数组中未定义或者undefined数据的情况。
    */
    const arraySparse = [1,3,,7];
    let forCallbackRuns = 0;
    let forEachCallbackRuns = 0;
    
    arraySparse.forEach(function(element){
      console.log(element);
      forEachCallbackRuns++;
    });
    
    console.log("forEachCallbackRuns: ", forEachCallbackRuns);
    
    /*
    1
    3
    7
    numCallbackRuns: 3
    */
    
    
    for(var i = 0; i < arraySparse.length ; i++){
      console.log(arraySparse[i]);
      forCallbackRuns++;
    }
    console.log("forCallbackRuns: ", forCallbackRuns);
    
    /*
    1
    3
    undefined
    7
    forCallbackRuns:  4
    */
    
    
    /*
    	数组中含有null数据的情况。
    */
    const arraySparse = [1,3,null,7];
    let forCallbackRuns = 0;
    let forEachCallbackRuns = 0;
    
    arraySparse.forEach(function(element){
      console.log(element);
      forEachCallbackRuns++;
    });
    
    console.log("forEachCallbackRuns: ", forEachCallbackRuns);
    
    /*
    1
    3
    null
    7
    forEachCallbackRuns:  4
    */
    
    
    for(var i = 0; i < arraySparse.length ; i++){
      console.log(arraySparse[i]);
      forCallbackRuns++;
    }
    console.log("forCallbackRuns: ", forCallbackRuns);
    
    /*
    1
    3
    null
    7
    forCallbackRuns:  4
    */
    
    

    注意

    除了抛出异常以外,没有办法中止或跳出 forEach() 循环。如果你需要中止或跳出循环,forEach() 方法不是应当使用的工具。

    若你需要提前终止循环,你可以使用:

    这些数组方法则可以对数组元素判断,以便确定是否需要继续遍历:

    译者注:只要条件允许,也可以使用 filter() 提前过滤出需要遍历的部分,再用 forEach() 处理。

    参考资料链接

    作者:Haiya_32ef 链接:https://www.jianshu.com/p/c43f418d6bf0

    作者:weixin_34128411 链接:https://blog.csdn.net/weixin_34128411/article/details/94279246

  • 相关阅读:
    CSS-calc 兼容写法
    一行代码轻松搞定各种IE兼容问题,IE6,IE7,IE8,IE9,IE10
    地图调起URI API(通过连接直接调用百度地图)
    获取字体图标(阿里图标网站)
    CSS-解决苹果点击高亮、安卓select灰色背景(select下拉框在IOS中背景变黑、出现阴影问题)
    移动端 input 输入框实现自带键盘“搜索“功能并修改X
    常用正则表达式—邮箱(Email)
    JS正则表达式验证是否为11位有效手机号码
    input,textarea在ios和Android上阴影和边框的处理方法(在移动端)
    three.map.control
  • 原文地址:https://www.cnblogs.com/Scooby/p/12160013.html
Copyright © 2011-2022 走看看