记录遍历方法

在ES5中经常使用的10种数组遍历方法:

一、原始的for循环语句
二、Array.prototype.forEach数组对象内置方法
三、Array.prototype.map数组对象内置方法
四、Array.prototype.filter数组对象内置方法
五、Array.prototype.reduce数组对象内置方法
六、Array.prototype.some数组对象内置方法
七、Array.prototype.every数组对象内置方法
八、Array.prototype.indexOf数组对象内置方法
九、Array.prototype.lastIndexOf数组对象内置方法
十、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循环的改良的两种写法:
bash

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

Exampleui

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循环实现的例子供你们参考理解:
this

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

Examplespa

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循环实现例子供你们参考:
Exampleprototype

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

Examplecode

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语句不一样的是它不能够循环对象,只能循环数组。

相关文章
相关标签/搜索