博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Javascript 10种遍历方法
阅读量:4968 次
发布时间:2019-06-12

本文共 9976 字,大约阅读时间需要 33 分钟。

 JS遍历简述

对于数组,javascript有很多遍历的方法,for、for in、for of(ES6)、forEach、map、filter、every、some、Jquery的each等等。接下来通过一些例子来对比一下这些方法。示例均使用如下测试数据:

var arr = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];

 

1. for 循环

for循环语句,最基础的遍历,以数组的下标为索引,对数组元素进行遍历。

示例:

1 function arrFor(arr) { 2     try { 3         var ret = '', 4             st = performance.now(); 5         for (var k = 0; k < arr.length; k++) { 6             ret += arr[k]; 7         } 8         console.log(ret); 9         var diff = performance.now() - st;10         console.log("array for 总耗时:" + diff);11     } catch (e) {12         console.log("array for 报错了:" + e.message);13     }14 }

 

 结果(Google):

abcdefghijklmnopqrstuvwxyzarray for 总耗时:1.7999999690800905

 

 结果(IE11):

abcdefghijklmnopqrstuvwxyzarray for 总耗时:0.6000000000000085

 

 for 循环不是函数,不存在返回值。

 2. for in

 for in循环不仅可以遍历数组,还可以遍历对象,但for in存在一些陷阱,比如它会在遍历完元素之后,还会对数组或对象的prototype中的属性进行遍历,所以,for in 更像是为对象遍历而设计的。

 示例: 

1 function arrForIn(arr) { 2     try { 3         var ret = '', 4             st = performance.now(); 5         for (var k in arr) { 6             ret += arr[k]; 7         } 8         console.log(ret); 9         var diff = performance.now() - st;10         console.log("array for in 总耗时:" + diff);11     } catch (e) {12         console.log("array for in报错了:" + e.message);13     }14 }

  

结果(Google):

abcdefghijklmnopqrstuvwxyzarray for in 总耗时:1.5999999595806003

 

 结果(IE11):

abcdefghijklmnopqrstuvwxyzarray for in 总耗时:0.7000000000000028

 

2.A 陷阱

在此,我们为数组做一点改动,在调用上面定义的 arrForIn 方法前先执行如下语句:

Array.prototype.name="this is a test";

 

结果(Google):

abcdefghijklmnopqrstuvwxyzthis is a testarray for in 总耗时:2.299999992828816

 

 结果(IE11):

abcdefghijklmnopqrstuvwxyzthis is a testarray for in 总耗时:0.5999999999999943

 

可以明显看到,打印出的字符串后面有 "this is a test",这就是 Array.prototype.name 的值。也就是说,Array 的原型也参与了遍历,这就给后续的语句埋下了一个炸弹。

当然,针对这种情况,也是有解决办法的,可以使用对象的hasOwnProperty()方法来避免此问题,通过hasOwnProperty()方法筛选出的都是对象实例自身的属性,对于像上面这种从Array继承过来的属性,该方法将返回false。

修改:

1 function arrForIn(arr) { 2     try { 3         var ret = '', 4             st = performance.now(); 5         for (var k in arr) { 6             if (arr.hasOwnProperty(k)) { 7                 ret += arr[k]; 8             } 9         }10         console.log(ret);11         var diff = performance.now() - st;12         console.log("array for in 总耗时:" + diff);13     } catch (e) {14         console.log("array for in报错了:" + e.message);15     }16 }

 

结果(Google):

abcdefghijklmnopqrstuvwxyzarray for in 总耗时:2.3999999975785613

 

对于数组的遍历,不提倡 for in

2.B IE兼容性

示例:

1 function arrForIn(arr) { 2     try { 3         //解决IE9不支持performance 4         if ((window.navigator.userAgent.indexOf("MSIE 9.0") >= 1) && window.performance) { 5             window.performance.now = function () { 6                 return ((+new Date()) - performance.timing.navigationStart); 7             } 8         } 9         var ret = '',10             st = performance.now();11         for (var k in arr) {12             ret += arr[k];13         }14         console.log(ret);15         var diff = performance.now() - st;16         console.log("array for in 总耗时:" + diff);17     } catch (e) {18         console.log("array for in报错了:" + e.message);19     }20 }

 

 

IE 10:

abcdefghijklmnopqrstuvwxyzarray for in 总耗时:0.5999999999999943

 

IE 9:

abcdefghijklmnopqrstuvwxyzarray for in 总耗时:1

  

 测试到IE9,都是支持的。 

3. for of (ES6)

ES6中引入了 for ... of 循环,以替代 for...in 和 forEach() ,允许对 Array(数组)、String(字符串)、Maps(映射)、Sets(集合)等可迭代的数据结构进行遍历。

1 function arrForOf(arr) { 2     try { 3         var ret = '', 4             st = performance.now(); 5         for(var k of arr) { 6             ret += k; 7         } 8         console.log(ret); 9         var diff = performance.now() - st;10         console.log("array for of 总耗时:" + diff);11     } catch (e) {12         console.log("array for of报错了:" + e.message);13     }14 }

需要注意的是:

1、 for(var k of arr) 中的 k ,就是数组 arr 中的元素,而不是数组的下标。

2、 IE 不支持,Edge支持。

 

结果(Google):

abcdefghijklmnopqrstuvwxyzarray for of 总耗时:2.3999999975785613

  

4. forEach

forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。

1 function arrForEach(arr) { 2     try { 3         var ret = '', 4             st = performance.now(); 5         arr.forEach(function (v, k) { 6             ret += v; 7         }); 8         console.log(ret); 9         var diff = performance.now() - st;10         console.log("array forEach 总耗时:" + diff);11     } catch (e) {12         console.log("array forEach报错了:" + e.message);13     }14 }

 

 结果(Google): 

abcdefghijklmnopqrstuvwxyzarray forEach 总耗时:1.7000000225380063

 

  结果(IE11):

abcdefghijklmnopqrstuvwxyzarray forEach 总耗时:1

 

注意:

  •  forEach() 对于空数组是不会执行回调函数的。
  • 回调函数  function (v, k) 中的 k 是数组的下标,v 是数组元素值。
  • IE9以下的版本不支持。

 

浏览器支持:

 

 5. map

 map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。

1 function arrMap(arr) { 2     try { 3         var ret = '', 4             st = performance.now(); 5         arr.map(function (v, k) { 6             ret += v; 7         }); 8         console.log(ret); 9         var diff = performance.now() - st;10         console.log("array map 总耗时:" + diff);11     } catch (e) {12         console.log("array map报错了:" + e.message);13     }14 }

  

结果(Google): 

abcdefghijklmnopqrstuvwxyzarray map 总耗时:1.5999999595806003

 

结果(IE11):

abcdefghijklmnopqrstuvwxyzarray map 总耗时:0.8000000000000114

  

 浏览器支持:

 

  •  map() 返回一个新数组。
  •  map() 不会对空数组进行检测。
  •  map() 不会改变原始数组。

接下来看一下map处理的结果,先修改一下操作:

function arrMap(arr) {    try    {        var newArr = arr.map(function(v, k) {            return v + 0;        });        console.log(arr.join(','));        console.log(newArr.join(','));    }    catch (e)    {        console.log("array map报错了:" + e.message);    }}

 

 输出结果

a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,za0,b0,c0,d0,e0,f0,g0,h0,i0,j0,k0,l0,m0,n0,o0,p0,q0,r0,s0,t0,u0,v0,w0,x0,y0,z0

 

可以看出

  • map()处理后不会改变原有数组
  • 新数组与原数组的元素个数一致

 6. filter

 filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。

1 function arrFilter(arr) { 2     try { 3         var ret = '', 4             st = performance.now(); 5         arr.filter(function (v, k) { 6             ret += v; 7         }); 8         console.log(ret); 9         var diff = performance.now() - st;10         console.log("array filter 总耗时:" + diff);11     } catch (e) {12         console.log("array filter报错了:" + e.message);13     }14 }

  

 结果(Google): 

abcdefghijklmnopqrstuvwxyzarray filter 总耗时:1.6000000177882612

  

结果(IE11):

abcdefghijklmnopqrstuvwxyzarray filter 总耗时:0.5999999999999943

 

浏览器支持:

 

  • filter() 不会对空数组进行检测。
  • filter() 不会改变原始数组。

 接下来看一下filter处理的结果,先修改一下操作:

function arrFilter(arr) {    try    {        var newArr = arr.filter(function(v, k) {            return k > 10;        });        console.log("arr:" + arr.join(','));        console.log("newArr:" + newArr.join(','));    }    catch (e)    {        console.log("array filter报错了:" + e.message);    }}

 

 结果(Google): 

arr:a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,znewArr:l,m,n,o,p,q,r,s,t,u,v,w,x,y,z

 

  • filter() 没有改变原始数组。
  • filter() 返回的新数组是筛选后的结果。

 7. every

every() 方法用于检测数组所有元素是否都符合指定条件(通过函数提供),返回 boolen。

1 function arrEvery(arr) { 2     try { 3         var st = performance.now(); 4         var ret = arr.every(function (v, k) { 5             return v.length > 1; 6         }); 7         console.log(ret); 8         var diff = performance.now() - st; 9         console.log("array every 总耗时:" + diff);10     } catch (e) {11         console.log("array every报错了:" + e.message);12     }13 }

 

 结果(Google): 

falsearray every 总耗时:1.500000013038516

 

结果(IE11):

falsearray every 总耗时:0.5

  

浏览器支持:

 

  • 如果数组中检测到有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测。
  • 如果所有元素都满足条件,则返回 true。
  •  every() 不会对空数组进行检测。
  • every() 不会改变原始数组。

 

 8. some

 some() 方法用于检测数组中的元素是否满足指定条件(函数提供)。只要有一个元素满足则返回true,并不再继续往下判断。

1 function arrSome(arr) { 2     try { 3         var st = performance.now(); 4         var ret = arr.some(function (v, k) { 5             return v.length > 1; 6         }); 7         console.log(ret); 8         var diff = performance.now() - st; 9         console.log("array some 总耗时:" + diff);10     } catch (e) {11         console.log("array some报错了:" + e.message);12     }13 }

  

  结果(Google): 

falsearray some 总耗时:1.6999999643303454

  

 结果(IE11):

falsearray some 总耗时:1.1000000000000227

  

 浏览器支持:

 

 

  • 如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。
  • 如果没有满足条件的元素,则返回false。
  • some() 不会对空数组进行检测。
  • some() 不会改变原始数组。

9. JQuery方法 $.each

each() 方法为每个匹配元素规定要运行的函数。JQuery的each方法既可以遍历数组,也可以遍历对象。在遍历对象时可以很容易获取对象属性名。

function jqueryEach(obj) {    try {        var ret = '',            st = performance.now();        $.each(obj, function(k, v) {            ret += v;        });        console.log(ret);        var diff = performance.now() - st;        console.log("jquery each 总耗时:" + diff);    } catch(e) {        console.log("jquery each报错了:" + e.message);    }}

 

  结果(Google): 

abcdefghijklmnopqrstuvwxyzjquery each 总耗时:2.8999999922234565

 

 结果(IE11):

abcdefghijklmnopqrstuvwxyzjquery each 总耗时:0.6999999999999886

 

  • 一般用法为:$(selector).each(function(index,element)) 或者 $.each(obj,function(index,element)) ;回调函数中 index 参数是 对象obj的属性名(或者 数组obj 的索引),element 参数是 具体的值。
  • 执行 return true 相当于 continue;
  • 执行 return false 相当于 break;

 

10. Object.keys.forEach

Object.keys.forEach() 主要是用于遍历对象,获取对象的属性名,对于遍历数组意义不大。

function objectKey(obj) {    try    {        var ret = '',            st = performance.now();        Object.keys(obj).forEach(function(key, index, arr) {            ret += obj[key];        });        //ES6写法        //Object.keys(obj).forEach(k => {
// ret += obj[k]; //});  console.log(ret); let diff = performance.now() - st; console.log("object key 总耗时:" + diff); } catch (e) { console.log("object key 报错了:" + e.message); }}

 

  结果(Google): 

abcdefghijklmnopqrstuvwxyzobject key 总耗时:1.799999998183921

 

 结果(IE11):

abcdefghijklmnopqrstuvwxyzobject key 总耗时:1.1000000000000227

 

  • Object.keys.forEach 在遍历时,回调函数的参数 key是属性名(对于数组,属性名和索引一一对应),index 是keys数组的索引,arr是keys数组;所以在取值的时候还是用 obj[key]

 

以上列出了10种在js中用到的遍历方法,有些地方描述的不是特别清晰,可能还存在误人子弟的地方,如果有大佬发现了还望及时指出,自已发现了也会及时更新的。

对于遍历,可能还有其他办法,以后发现了会继续记录。

 

作者:乔二哥

加班码字不易    文章暂不允许私自转载,转载请在明显的地方标注文章出处。

转载于:https://www.cnblogs.com/qiaoge0923/p/9594539.html

你可能感兴趣的文章
委托的调用
查看>>
c#中从string数组转换到int数组
查看>>
数据模型(LP32 ILP32 LP64 LLP64 ILP64 )
查看>>
java小技巧
查看>>
POJ 3204 Ikki's Story I - Road Reconstruction
查看>>
【BZOJ】2959: 长跑(lct+缩点)(暂时弃坑)
查看>>
iOS 加载图片选择imageNamed 方法还是 imageWithContentsOfFile?
查看>>
toad for oracle中文显示乱码
查看>>
SQL中Group By的使用
查看>>
错误org/aopalliance/intercept/MethodInterceptor解决方法
查看>>
两个表格中数据不用是一一对应关系--来筛选不同数据,或者相同数据
查看>>
客户数据库出现大量cache buffer chains latch
查看>>
機械の総合病院 [MISSION LEVEL: C]
查看>>
实战练习细节(分行/拼接字符串/字符串转int/weak和copy)
查看>>
Strict Standards: Only variables should be passed by reference
查看>>
hiho_offer收割18_题解报告_差第四题
查看>>
AngularJs表单验证
查看>>
静态方法是否属于线程安全
查看>>
02号团队-团队任务3:每日立会(2018-12-05)
查看>>
SQLite移植手记1
查看>>