前言

最近看了好几篇总结数组中遍历方法的文章,然而“纸上得来终觉浅”,决定此事自己干。于是小小总结,算是自己练手了。

各种数组遍历方法

数组中常用的遍历方法有四种,分别是:

for

for-in

forEach

for-of (ES6)

for

使用for循环来遍历一个数组,代码如下:

// for循环

let arr=[2,4,6,10];

for(let i=0;i

console.log(arr[i]);

}

当数组的长度不回改变时,我们使用一个变量来存储数组的长度arr.length,以获得更好的效率(因为每次比较的时候都省去计算arr.length)。改进后的算法如下:

// for循环

let arr=[2,4,6,10];

for(let i=0,len=arr.length;i

console.log(arr[i]);

}

当然如果不考虑输出顺序,为了简化,也可以使用i--,代码如下:

// for循环

let arr=[2,4,6,10];

for(let i=arr.length;i>=0;i--){

console.log(arr[i]);

}

for-in

通常情况下,我们可以这样使用:

//for-in 循环

let arr=[2,4,6,10];

let index;

for (index in arr){

console.log(arr[index]);

}

输出结果

arr[0]=2

arr[1]=4

arr[2]=6

arr[3]=10

来,我们再看一个例子:

//for-in 循环

let per={

name:"zhang San",

sex:'male',

age:18

};

for(let key in per){

console.log("per[" + key + "]=" + per[key]);

}

输出结果

per[name]=zhang San

per[sex]=male

per[age]=18

根据上面的两个例子可以看到,for-in不仅可以遍历数组还可以遍历对象。

注意:文章深入了解 JavaScript 中的 for 循环 指出for-in 遍历属性的顺序并不确定,即输出的结果顺序与属性在对象中的顺序无关,也与属性的字母顺序无关,与其他任何顺序也无关。,但是我在实际操作中,发现输出一直是上面的结果,即其按照了定义属性的顺序输出了。

此时,我们回头再次看一个for-in的例子:

Array.prototype.fatherName = "Father";

let arr=[2,4,6,10];

arr.name="hello,world!";

let index;

for (index in arr){

console.log('arr['+index+']='+arr[index]);

}

输出结果

arr[0]=2

arr[1]=4

arr[2]=6

arr[3]=10

arr[name]=hello,world!

arr[Father]=Father

我们发现一个问题,使用for-in在遍历的时候,它不仅遍历了对象上的属性,而且还遍历了对象父类原型上的属性。

所以for-in并不适合遍历Array中的元素,更适合遍历对象中的属性,这也是创造for-in的初衷。但是对于稀疏数组,使用它却是极好的。例子如下:

let key;

let arr = [];

arr[0] = "a";

arr[999] = "b";

arr[99999] = "c";

for(key in arr) {

if(arr.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 100000) {

console.log(arr[key]);

}

}

在上面的例子当中,由于for-in只会遍历存在的实体,因此使用for-in循环,只需要遍历3次,而使用for循环则需要遍历100000次。

for-in的性能

由于使用它的时候,每次需要遍历对象中存在的实体,以及对应的原型链上的属性。因此其速度相比较其他for循环,要慢一些。所以除非明确要迭代一个属性数量未知的对象,否则应该避免使用for-in。

forEach

forEach()方法为数组中的每一个有效元素执行一次callback函数。遍历数组让数组中的每一个元素做一件事情。那些已经被删除(使用delete方法等情况)或者未初始化的项将被跳过(但不包含那些值未undefined的项目)。

注意,callback函数将依次被传入3个参数:

数组当前项的值

数组当前项的索引

数组对象本身

看个例子:

let arr = [];

arr[0] = "a";

arr[3] = "b";

arr[10] = "c";

arr[name] = "Hello world";

arr.forEach((data, index, array) => {

console.log(data, index, array);

});

输出结果

a 0 ["a", 3: "b", 10: "c", name: "Hello world"]

b 3 ["a", 3: "b", 10: "c", name: "Hello world"]

c 10 ["a", 3: "b", 10: "c", name: "Hello world"]

值得注意的是:

没有输出name。why? 因为name是arr的属性,而0,3,10都是arr的索引。

这里的 index 是 Number 类型,并且也不会像 for-in 一样遍历原型链上的属性。

forEach的性能

在不同浏览器下测试的结果都是 forEach 的速度不如 for。可以看到forEach主要应用在遍历数组,但是它的性能并不如for,因此可以使用for就尽量不要使用forEach。

for-of(ES6中新增)

for-of是ES6中新增的一个遍历数组或者类数组的方法。它的出现主要是为了解决ES5中3种遍历方式的缺陷:

forEach 不能break 或者return

for-in 的缺点更加明显。它不仅遍历了数组中的元素,还遍历了自定义属性,甚至连原型链上的属性都被访问到。

因此使用for-of的优势在于:

这是最简洁、直接遍历数组的方式

这个方法避开了for-in循环的缺陷

与forEach不同,它可以正确响应break,continue,return 语句。

说了这么多for-of的优点,那么它有没有缺点呢?

for-of不支持普通对象遍历,如果想要遍历普通对象,使用for-in

例子:

let arr=[3,7,9];

for (let key of arr){

console.log(key);

}

结果

3

7

9

性能

由于for-of也是只遍历可迭代对象的数据,相比于for-in,效率会更高。

Other 循环方法

说明:下面的方法,Map,Reduce,Filter,Every,some方法都是面向数组的。不是普通对象。

map(不改变原数组)

map方法(映射)给数组中的每个元素执行一次callback函数,执行callback函数的返回值组成一个新数组。未被初始化项、已经被删除项(使用delete等方法)、数组的属性不会被执行callback函数。

请看如下例子:

let arr=new Array(5);

arr[1]=1;

arr[2]=2;

arr.name="hello,world!";

delete(arr[2]);

let fireArr=arr.map(item=>item*5);

console.log(fireArr);

输出结果:

[empty,5,empty,empty,empty]

reduce

reduce方法,让数组的前项后项进行某种计算。累计最终的结果。

例子:

//reduce方法

let arr = [4,7,8,3];

let total= arr.reduce( function (x, y) {

console.log(x);

return x + y;

});

console.log(total);

输出结果

4

11

19

22

filter(不改变原数组)

filter的意思是滤镜、过滤器,顾名思义就是用来筛选符合某种条件的元素,将符合条件的元素重新组成一个新的数组。

还是看一个例子:

let arr = [2,3,4,5,6];

arr.name=8;

let morearr = arr.filter(function (number) {

return number > 3

});

console.log(morearr);

输出结果

4, 5, 6

在上面的例子中,将大于索引大于3的元素输出。而不会输出属性。

every

every方法为数组中的每个元素执行一次 callback 函数,当它找到一个使 callback 返回 false(表示可转换为布尔值 false 的值)的元素,就立刻返回false。否则,callback为每个元素返回true,every就返回true。

看一面的例子

let arr = [1,2,3,4,5];

let result = arr.every(function (item, index) {

return item > 0

});

console.log(result);

返回结果

true

some

some为数组中的每一个元素执行一次 callback 函数,直到找到一个使得 callback 返回一个“真值”(即可转换为布尔值 true 的值)。如果找到了这样一个值,some 将会立即返回 true。否则,some 返回 false。

let arr = [1,2,3,4,5];

let result = arr.some(function (item,index) {

return item > 3

});

console.log(result);

iterator

最后,还有一个东西不得不介绍,ES6新增的iterator,迭代器。

看例子:

const arr = ['a', 'b', 'c'];

const iter = arr[Symbol.iterator]();

iter.next() // { value: 'a', done: false }

iter.next() // { value: 'b', done: false }

iter.next() // { value: 'c', done: false }

iter.next() // { value: undefined, done: true }

iterator名叫“迭代器”,iter.next()实际上是探测下一个位置是否有数据的探测器,如果有就返回false;如果下一个位置上没有,就返回true。

效率问题

1、循环效率

for > for-of > forEach > filter > map > for-in

可以看到 的是for循环的速度是最快的,是最老的循环方法,也是优化得最好的;其次是for-of这个是es6才新增的循环非常好用,最慢是for-in,原因是它遍历了原型链上的属性。

2、some 和 every

他们都是根据判断条件,返回给整个数组Boolean 值的方法,every 的执行速度会比some快很多。

every是不满足判断条件后,立即返回“假的”false值给整个数组。否则继续执行,返回true。

some是满足判断条件后,立刻返回“真值”true给整个数组。否则继续执行,返回false。

java script 遍历数组_JavaScript中数组中遍历的方法相关推荐

  1. java script 菜鸟教程_JavaScript 菜鸟基础教程

    <JavaScript 菜鸟基础教程>由会员分享,可在线阅读,更多相关<JavaScript 菜鸟基础教程(21页珍藏版)>请在人人文库网上搜索. 1.JavaScript 简 ...

  2. Dao接口返回数组_JavaScript二进制数组(2)TypedArray视图

    ArrayBuffer对象作为内存区域可以存放多种类型的数据.同一段内存,不同数据有不同的解读方式,这种解读方式称为"视图(view)".ArrayBuffer有两种类型的视图,一 ...

  3. java+script+当前日期_如何在JavaScript中获取当前日期?

    如何在JavaScript中获取当前日期? #1楼 您可以使用扩展了 Date对象的Date.js库,从而可以使用.today()方法. #2楼 如果您想对日期格式进行更多的粒度控制,我强烈建议您查看 ...

  4. java script eval_「eval」js中的eval方法详解(一)–eval方法的初级应用 - seo实验室...

    eval 在我看来,js中的eval()方法就是一个js语言的执行器,它能把其中的参数按照javaScript语法进行解析并执行. 语法: eval(s); eval()方法中的参数s有多种情况.参数 ...

  5. java js 截取字符串_JavaScript:在JS中截取字符串的方法

    这篇主要说一说截取字符串的方法,用于帮助自己缕清方法的作用,参数的意义,返回值,是否对于原来的字符串进行了操作等. 在javascript中,常见的截取字符串的方法有slice().substring ...

  6. 转成数组_JavaScript之数组扁平化

    今天给大家分享一下JavaScript的数组扁平化. 1. 扁平化 数组的扁平化,就是将一个嵌套多层的数组 array (嵌套可以是任何层数)转换为只有一层的数组.举个例子,假设有个名为 flatte ...

  7. java script 月日年转年月日_javasrcipt日期一些方法和格式转化

    Js获取当前日期时间及其它操作 var myDate = new Date(); myDate.getYear();        //获取当前年份(2位) myDate.getFullYear(); ...

  8. java script error_java script error 错误解决方法

    用了动易这么久了,有时一不小心改错模版文件或者 修改相关的JS,就会导致页面出现一些奇怪了 的弹出框 说什么 java script error 错误,烦死了. 今天特别研究了下,找到了解决这类问题的 ...

  9. java 中数组的创建 数组遍历 以及数组的输出(打印)

    什么是数组? 如果我们需要创建一个 int 类型变量,那么我们只需要 int a; 如果我们需要创建五个 int 类型变量,那么我们只需要int a1; int a2; int a3; int a4; ...

最新文章

  1. centos下安装apache + subversion(转)
  2. 团队作业8——第二次项目冲刺(Beta阶段)--第六天
  3. golang strings Replace 字符串替换
  4. C#学习路线:C#入门经典 -> CLR VIA C# -> WINDOWS核心编程
  5. 中文URL是否有利于网站SEO
  6. 【转】推荐10本C#编程的最佳书籍
  7. Python操作MySQL数据库的三种方法
  8. 打印SAP Spartacus generic link指向的url
  9. python里的符号区别_Python中的方括号和点符号有什么区别?
  10. 逆置单链表c语言程序,(数据结构C语言版)顺序表和单链表的逆置
  11. 数据库作业[定时执行任务]的创建
  12. 世界上最奇异的10种树,你都见过吗?
  13. mysql服务连接标识_MySQL 连接 | 菜鸟教程
  14. amd u盘安装linux mint,安装Linux Mint 20后需要做的13件事
  15. yolo和mrcnn目标检测
  16. paip.验证码识别---除噪算法-中值滤波
  17. 海外资管业价格战有多疯狂?史上首个零费率基金横空出世
  18. 十五秒破解“还原卡”
  19. 功能安全标准-ISO26262-6---硬件集成测试
  20. 如何正确做笔记?符号笔记法、康奈尔笔记法总结!

热门文章

  1. 十、Redis五大数据类型之二List
  2. 计算一个image的大小_一个方案提升Flutter内存利用率(干货)
  3. linux安装 mysql-5.7.25_Linux 系统下安装 mysql5.7.25(glibc版)
  4. 存储过程mysql into select into_mysql 存储过程select into select into select的搜索结果-阿里云开发者社区...
  5. mongocollection java_mongodb与java的整合
  6. 冒泡排序出现的问题_停课不停学 | 有趣的算法——冒泡排序
  7. Linux中look命令,如何在Linux上使用look命令 | MOS86
  8. transforms函数查询
  9. 【408预推免复习】计算机网络(谢希仁第七版)第一章——概述
  10. python【力扣LeetCode算法题库】面试题40- 最小的k个数