JavaScript中数组中遍历的方法
前言
最近看了好几篇总结数组中遍历方法的文章,然而“纸上得来终觉浅”,决定此事自己干。于是小小总结,算是自己练手了。
各种数组遍历方法
数组中常用的遍历方法有四种,分别是:
- for
- for-in
- forEach
- for-of (ES6)
for
使用for循环来遍历一个数组,代码如下:
// for循环
let arr=[2,4,6,10];
for(let i=0;i<arr.length;i++){
console.log(arr[i]);
}
当数组的长度不回改变时,我们使用一个变量来存储数组的长度arr.length
,以获得更好的效率(因为每次比较的时候都省去计算arr.length
)。改进后的算法如下:
// for循环
let arr=[2,4,6,10];
for(let i=0,len=arr.length;i<len;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。
参考文档:
JavaScript 数组遍历方法的对比
深入了解 JavaScript 中的 for 循环
JavaScript中数组中遍历的方法的更多相关文章
- JavaScript从数组中删除指定值元素的方法
本文实例讲述了JavaScript从数组中删除指定值元素的方法.分享给大家供大家参考.具体分析如下: 下面的代码使用了两种方式删除数组的元素,第一种定义一个单独的函数,第二种为Array对象定义了一个 ...
- 总结Javascript中数组各种去重的方法
相信大家都知道网上关于Javascript中数组去重的方法很多,这篇文章给大家总结Javascript中数组各种去重的方法,相信本文对大家学习和使用Javascript具有一定的参考借鉴价值,有需要的 ...
- Javascript获取数组中的最大值和最小值的方法汇总
比较数组中数值的大小是比较常见的操作,下面同本文给大家分享四种放哪广发获取数组中最大值和最小值,对此感兴趣的朋友一起学习吧 比较数组中数值的大小是比较常见的操作,比较大小的方法有多种,比如可以使用 ...
- 将java中数组转换为ArrayList的方法实例(包括ArrayList转数组)
方法一:使用Arrays.asList()方法 1 2 String[] asset = {"equity", "stocks", "gold&q ...
- java中数组有没有length()方法?string没有lenght()方法?
java中数组有没有length()方法,求数组的长度可以使用数组的length属性. int[] arr={1,2,3,4,5}; int length=arr.length;//求数组的长度 -- ...
- Javascript 获得数组中相同或不同的数组元素
Javascript 获得数组中相同或不同的数组元素 在Javascript中,偶尔会用到获取数组中相同或不同的元素值的情况,以下提供了获得数组中相同或不同的 元素函数供参考学习使用. // 数字类型 ...
- javascript中数组的22种方法
× 目录 [1]对象继承 [2]数组转换 [3]栈和队列[4]数组排序[5]数组拼接[6]创建数组[7]数组删改[8]数组位置[9]数组归并[10]数组迭代[11]总结 前面的话 数组总共有22种方法 ...
- javascript中数组的22种方法 (转载)
前面的话 数组总共有22种方法,本文将其分为对象继承方法.数组转换方法.栈和队列方法.数组排序方法.数组拼接方法.创建子数组方法.数组删改方法.数组位置方法.数组归并方法和数组迭代方法共10类来进行详 ...
- JavaScript中数组中的方法:push()、pop()、shift()、unshift()、slice()、splice()、reverse()、join()、split()、concat()、indexOf()、forEach()、map()、
1.创建数组的几种方法 //a).通过new来创建数组,new可以省略 var arr=new Array(); var arr=Array(); //b). .通过new来创建数组,并且赋值 v ...
随机推荐
- 初识TCP/IP协议
初识TCP/IP协议 TCP/IP 全称是(Transmission Control Protocol / Internet Protocol),传输控制协议/网际协议.TCP/IP定义了电子设备(比 ...
- Spring源码分析(十五)获取单例
本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 之前我们讲解了从缓存中获取单例的过程,那么,如果缓存中不存在已经加载的单例be ...
- jq的innerWidth()遇到的坑
innerWidth()在元素隐藏的时候是取不到值的,但是取到的是元素的内部尺寸,包括padding和content值,,如果元素隐藏了之后他的content就为空,值为0,所以只有等到元素显示之后再 ...
- Php5.6.31连接sqlserver 2008R2数据库问题sqlsrv(php5.3及以上版本)与mssql(php5.3以前版本)②
Php5.6.31连接sqlserver 2008R2数据库 1.环境配置 Win7(win8.1) 64 +Apache2.4 + PHP5.6.31 + SQL Server 2008 R2数据 ...
- 解决安装macports更新失败问题
安装 macports 先是卡在开始,xcode的路径指定错误,重新指定一下,然后再sudo port selfupdate,就卡再ports.tar那里不动了.经过google和百度查到参考网 ...
- iOS Class结构分析
objc_class结构体 类在OC中是objc_class的结构体指针 typedef struct objc_class *Class; 在objc/runtime.h中objc_class结构体 ...
- Flask租房项目总结
该Flask项目历时3天,开发小组6人,目的是开发一个租房web项目,该项目采用前后端分离模式. Flask租房项目总结 分析需求文档,需要完成的功能模块有: 登陆注册 首页展示,首页搜索 详情展示, ...
- echarts显示X轴最后一个lable
代码: xAxis: [ { axisLabel: { showMaxLabel: true } } ]
- Hadoop的HDFS和MapReduce的安装(三台伪分布式集群)
一.创建虚拟机 1.从网上下载一个Centos6.X的镜像(http://vault.centos.org/) 2.安装一台虚拟机配置如下:cpu1个.内存1G.磁盘分配20G(看个人配置和需求,本人 ...
- scala字段权限问题
1.对象私有字段 1)private class Counter(num: Int) { private var value = 0 def increment() = { value += 1 } ...