ES5和ES6数组遍历要领详解
在ES5中经常运用的10种数组遍历要领:
1、原始的for轮回语句
2、Array.prototype.forEach数组对象内置要领
3、Array.prototype.map数组对象内置要领
4、Array.prototype.filter数组对象内置要领
5、Array.prototype.reduce数组对象内置要领
6、Array.prototype.some数组对象内置要领
7、Array.prototype.every数组对象内置要领
8、Array.prototype.indexOf数组对象内置要领
9、Array.prototype.lastIndexOf数组对象内置要领
10、for…in轮回语句
ES6中新增加了一种:
1.for…of轮回语句
ES5三种数组轮回示例以下:
原始for轮回语句
Example1
var a = [1,2,3];
for(var i=0;i<a.length;i++){
console.log(a[i]); //结果依次为1,2,3
}
代码解读:原始for轮回的长处在于人人都比较熟习,轻易明白,劣势是写起来比较烦琐,须要定义分外更多的变量,所以一下是针关于原始for轮回的改进的两种写法:
Example1:写法改进版
var a = [1,2,3];
for(var i=a.length;i--;){
console.log(a[i]); //结果依次为3,2,1
}
Example2:机能改进版
var a = [1,2,3];
for(var i = 0,len=a.length; i < len; i++) {
console.log(a[i]); //结果依次为1,2,3
}
注重:以上代码能够写成如许呢,假如懵逼了的话接着看原始for轮回的解读,我们都晓得for轮回包括三个语句块——>for(语句1;语句2;语句3){被实行的代码},个中,语句1平常为变量定义语句(不仅能够只定义一个变量哦),在轮回最先前实行,而且只实行一次;语句2定义轮回的是不是继承实行的前提,一样也是在轮回最先前实行,语句1以后实行,每次重新最先轮回都邑再次实行;语句3则在轮回完毕以后实行,而且每次完毕的时刻都邑再次实行,这里要注重的是假如被实行的代码半途return出来了那是不会再实行一次语句3的,所以以上代码诠释以下:因为i–这个语句在每次轮回最先前都邑再次先用 i 是true和false来推断是不是继承实行,这里一样要注重的是因为i–和–i的区分,这里因为是i–所以会先推断i的值再去做‘减减’的操纵,所以这里末了假如打印 i 的值,会发明实际上是-1。
数组内置要领Array.prototype.forEach
Example
var a = [1,2,3];
a.forEach(function(value,key,arr){
console.log(value) // 结果依次为1,2,3
console.log(key) // 末端依次为0,1,2
console.log(arr) // 三次结果都为[1,2,3],该参数貌似没什么用
})
代码解读:forEach要领最大的优点就是便于运用,而且不必定义分外的参数变量,然则从效力以及机能角度来讲它是劣于原始for轮回的,而且也不能强迫return完毕轮回,缘由以下:
**forEach轮回**一看就是经由历程**回调函数**来供应参数的,而回调函数在JS中是**闭包**的一种,闭包的作用是用来天生**私有作用域**的,所以,每个回调函数都是一个**自力的作用域**,都具有自身自力的存储空间,互不影响,而且内部变量还不实时开释,这也就是为何在能不必闭包的情况下就不要用闭包的缘由,而在闭包中return的话,也只是在当前回调函数中返回了,但是forEach中的其他的回调函数(闭包)依然存在,所以,致使return是没办法完毕轮回的。下面写一个forEach轮回完成例子供人人参考明白:
Example
Array.prototype.forEachCopy = function(callback){
var arr = this;
for(var i=0;i<arr.length;i++){
callback(arr[i],i,this);
}
}
var a = [1,2,3];
a.forEachCopy(function(value,key,arr){
console.log(value) // 结果依次为1,2,3
console.log(key) // 末端依次为0,1,2
console.log(arr) // 三次结果都为[1,2,3]
})
数组内置要领Array.prototype.map
Example
var a = [1,2,3];
var b = a.map(function(value,key,arr){
console.log(value) // 结果依次为1,2,3
console.log(key) // 末端依次为0,1,2
console.log(arr) // 三次结果都为[1,2,3]
return value+1;
})
console.log(a); // 结果为[ 1, 2, 3 ]
console.log(b); // 结果为[ 2, 3, 4 ]
代码解读:map和forEach差别,在forEach中return语句是没有任何结果的,而map则能够转变当前轮回的值,而且最终会返回一个新的被转变过值以后的数组(map假如不必return就和forEach一样了),因为这个特征,map平常用来处置惩罚须要修正某一个数组的值。map和forEach在其他的方面都是一样的,也不能return完毕轮回等特征,下面写一个map轮回完成的例子供人人参考明白:
Example
Array.prototype.mapCopy = function(callback){
var arr = this;
var arrCopy = [];
for(var i=0;i<arr.length;i++){
var cbValue = callback(arr[i],i,this);
arrCopy.push(cbValue);
}
return arrCopy;
}
var a = [1,2,3];
var b = a.mapCopy(function(value,key,arr){
console.log(value) // 结果依次为1,2,3
console.log(key) // 末端依次为0,1,2
console.log(arr) // 三次结果都为[1,2,3]
return value+1;
})
console.log(a); // 结果为[ 1, 2, 3 ]
console.log(b); // 结果为[ 2, 3, 4 ]
数组内置要领Array.prototype.filter
Example
var a = [1,2,3];
var b = a.filter(function(value,key,arr){
console.log(value) // 结果依次为1,2,3
console.log(key) // 末端依次为0,1,2
console.log(arr) // 三次结果都为[1,2,3]
if(value === 3){
return false;
}
return true;
})
console.log(a); // 结果为[ 1, 2, 3 ]
console.log(b); // 结果为[ 1,2 ]
代码解读:filter和map差别,map目标是为了转变值,而filter目标是为了去掉不要的值,在轮回的时刻假如返回的是false那末就示意本次轮回的不增加该值,返回true则相反是示意要增加到新建的数组中,下面写一个filter轮回完成例子供人人参考:
Example
Array.prototype.filterCopy = function(callback){
var arr = this;
var arrCopy = [];
for(var i=0;i<arr.length;i++){
var cbValue = callback(arr[i],i,this);
if(cbValue){
arrCopy.push(arr[i]);
}
}
return arrCopy;
}
var a = [1,2,3];
var b = a.filterCopy(function(value,key,arr){
console.log(value) // 结果依次为1,2,3
console.log(key) // 末端依次为0,1,2
console.log(arr) // 三次结果都为[1,2,3]
if(value === 3){
return false;
}
return true;
})
console.log(a); // 结果为[ 1, 2, 3 ]
console.log(b); // 结果为[ 1,2 ]
数组内置要领Array.prototype.reduce
Example
var a = [1,2,3];
var b = a.reduce(function (count, value,key,arry) {
console.log(count); // 结果依次为0,1,3
console.log(value); // 结果依次为1,2,3
console.log(key); // 结果依次为0,1,2
console.log(arry) // 三次结果都为[1,2,3]
return count + value;
},0);
console.log(a); // 结果为[ 1, 2, 3 ]
console.log(b) // 结果为6
代码解读:reduce的差别之处在于累加,和其他几个内置要领差别的处所,它的第二个参数不是this对象,而是初始累加值(假如不设置的话数组会乱掉),而且回调函数的的个数也差别,比其他的多了一个,而且还在在最先的多加了一个参数,第一个参数纪录的是上一次轮回的累加值,下面写一个reduce轮回完成例子供人人参考:
Example
Array.prototype.reduceCopy = function(callback,countInit){
var arr = this;
for(var i=0;i<arr.length;i++){
var cbValue = callback(countInit,arr[i],i,this);
countInit = cbValue;
}
return countInit;
}
var a = [1,2,3];
var b = a.reduceCopy(function (count, value,key,arry) {
console.log(count); // 结果依次为0,1,3
console.log(value); // 结果依次为1,2,3
console.log(key); // 结果依次为0,1,2
console.log(arry) // 三次结果都为[1,2,3]
return count + value;
},0);
console.log(a); // 结果为[ 1, 2, 3 ]
console.log(b) // 结果为6
数组内置要领Array.prototype.some
Example
var a = [1,2,3];
var b = a.some(function(value,key,arry){
console.log(value); // 结果依次为1,2
console.log(key); // 结果依次为0,1
console.log(arry); // 两次次结果都为[1,2,3]
return value===2;
})
console.log(a); // 结果为[ 1, 2, 3 ]
console.log(b); // 结果为true
代码解读:some的差别之处在它返回的布尔值,它的作用有点像filter,不过它的目标不是为了挑选返回数组,而是为了挑选该数组是不是有满足你要的值,而且找到相符前提的值返回了一次true以后就不会再继承实行了,下面写一个some轮回完成例子供人人参考:
Example
Array.prototype.someCopy = function(callback,countInit){
var arr = this;
var isBool = false;
for(var i=0;i<arr.length;i++){
var cbValue = callback(arr[i],i,this);
if(cbValue){
isBool = true;
return isBool
}
}
return isBool;
}
var a = [1,2,3];
var b = a.someCopy(function(value,key,arry){
console.log(value); // 结果依次为1,2
console.log(key); // 结果依次为0,1
console.log(arry); // 两次次结果都为[1,2,3]
return value===2;
})
console.log(a); // 结果为[ 1, 2, 3 ]
console.log(b); // 结果为true
数组内置要领Array.prototype.every
Example
var a = [1,2,3];
var b = a.every(function(value,key,arry){
console.log(value); // 结果依次为1,2
console.log(key); // 结果依次为0,1
console.log(arry); // 两次次结果都为[1,2,3]
return value===2;
})
console.log(a); // 结果为[ 1, 2, 3 ]
console.log(b); // 结果为false
代码解读:实在从看例子能够看出来,some和every作用是一样的,只不过some当找到以后返回的是true,而every找到以后返回的是false罢了,下面写一个every轮回完成例子供人人参考:
Example
Array.prototype.everyCopy = function(callback){
var arr = this;
var isBool = true;
for(var i=0;i<arr.length;i++){
var cbValue = callback(arr[i],i,this);
if(cbValue){
isBool = false;
return isBool
}
}
return isBool;
}
var a = [1,2,3];
var b = a.everyCopy(function(value,key,arry){
console.log(value); // 结果依次为1,2
console.log(key); // 结果依次为0,1
console.log(arry); // 两次次结果都为[1,2,3]
return value===2;
})
console.log(a); // 结果为[ 1, 2, 3 ]
console.log(b); // 结果为false
数组内置要领Array.prototype.indexOf
Example
var a = [1,2,3];
var b = a.indexOf(2);
console.log(a); // 结果为[ 1, 2, 3 ]
console.log(b); // 结果为1
代码解读:关于indexOf要领来讲,在数组轮回历程中会和传入的参数比对,假如是比对胜利,那末停止轮回,返回对照胜利的下标,下面写一个indexOf轮回完成例子供人人参考:
Example
Array.prototype.indexOfCopy = function(value){
var arr = this;
var index = -1;
for(var i=0;i<arr.length;i++){
if(arr[i] === value){
index = i;
return index
}
}
return index;
}
var a = [1,2,3];
var b = a.indexOfCopy(2);
console.log(a); // 结果为[ 1, 2, 3 ]
console.log(b); // 结果为1
数组内置要领Array.prototype.lastIndexOf
Example
var a = [1,2,3,1];
var b = a.lastIndexOf(1);
console.log(a); // 结果为[ 1, 2, 3, 1 ]
console.log(b); // 结果为1
代码解读:lastIndexOf要领和indexOf作用一致,但查找方向差别,indexOf是正向查找,lastIndexOf是你像查找,找到以后返回胜利的下标,下面写一个lastIndexOf轮回完成例子供人人参考:
Example
Array.prototype.lastIndexOf = function(value){
var arr = this;
var index = -1;
for(var i=arr.length;i--;){
if(arr[i] === value){
index = i;
return index
}
}
return index;
}
var a = [1,2,3,1];
var b = a.lastIndexOf(1);
console.log(a); // 结果为[ 1, 2, 3 , 1 ]
console.log(b); // 结果为3
小结:关于以上8个数组的内置要领,forEach要领仅仅只是为了轮回,并不能够帮你做分外的事变;map要领相当于在轮回的时刻你通知数组当前遍历的这个值须要改成什么样,那末它就会末了给什么样的数组;filter要领相当于在轮回的时刻数组遍历一个个对象,并问你这个是不是是你要找的值,假如你说是,他就会给你返回一个到新的数组中,不是他就会剔除;reduce要领相当于轮回遍历对象做统计(累加或许累减之类的);some和every要领相当于在遍历的时刻拿着一个个对象问你这个是不是是你找的,只需你说了一遍是,那末他就会给你离别返回的是true和false;indexOf和lastIndexOf要领相当于你通知它你要找什么值,找到以后立马返回给你它的门牌号。
轮回语句for…in
Example
var a = [1,2,3];
for(var key in a){
console.log(key); //结果为依次为0,1,2
}
var b = {0:1,1:2,2:3};
for(var key in b){
console.log(key); //结果为依次为0,1,2
}
代码解读:从结果得知,for…in遍历数组的时刻是遍历数组的下标值,而在遍历对象的时刻遍历的是key值,所以猜测,数组在JS中,本质上也是一个以键值对情势存在的对象,而为了证实这点,我们做以下一个例子的试验:
var a = [];
a['b'] = 2;
console.log(a); //结果为[ b: 2 ]
console.log(a[0]); //结果为undefined
我们发明数组的下标不在对应响应位置的值了,由此能够证实在JS中数组实在本质上就是一个以下标为key值的对象。
固然关于for…in轮回语句自身而言,它是一个浅度遍历对象的轮回语句,值遍历第一层节点(固然对象中设置不可枚举的属性的除外)。
Example
var a = {b:{c:2},d:{c:4}};
for(var key in a){
console.log(key); //结果为依次为b,d
}
ES6轮回for…of语句
Example
var a = [1,2,3];
for(var value of a){
console.log(value) // 结果依次为1,2,3
}
代码解读:for…of语句看着有点像for…in语句,然则和for…in语句差别的是它不能够轮回对象,只能轮回数组。