javaScript数组之数组循环

Array,数组,是javaScript数据类型里面的引用类型的数据,在咱们前端开发的过程当中,能够说是使用的很是很是的频繁,而对数组的循环也是咱们最多见的操做,今天给你们分享一下我本身在前端开发过程当中对数组循环操做使用的一些我的经验和小技巧:前端

经常使用数组循环方法

  • for
  • for in
  • for of
  • forEach()
  • map()
  • some()
  • every()
  • filter()

for循环 `java

var arr = [{id: 1, color: 'red'}, {id: 2, color: 'orange'}, {id: 3, color: 'yellow'},
{id: 4, color: 'green'}, {id: 5, color: 'blue'} ];
for (var i = 0, len = arr.length; i < len; i++) {
    console.log(arr[i].color)    
}
// 输出: 'red', 'orange', 'yellow', 'green', 'blue'
复制代码

` 上面这个for循环应该是各位程序员使用的最最多的一个循环方式是吧,for循环是以声明一个变量i,初始值为0,只要i小于arr.length,i就加加一次,直到不小于为止,则跳出循环。你们在看这段代码的时候,是否有留意到,我把arr.length存储到一个len的变量中,注意哦,这个是for循环使用的小技巧哦,由于在咱们循环遍历数组的时候,若是没有事先存储,变量i在每次循环递增以前便会反复去计算数组的长度值,由于只要涉及到计算,确定就会消耗咱们的浏览器对js代码解析的性能,而当咱们存储起来,就优化了这个部分,这样作对于咱们前端开发来讲是很是有必要的呢,下面对for 循环作个总结:程序员

  • 一. 使用for循环时请把循环的对象的length存储起来;
  • 二. for循环可使用break中断循环;
  • 三. for循环不可使用return跳出循环;

for in循环 `es6

var arr = [{id: 1, color: 'red'}, {id: 2, color: 'orange'}, {id: 3, color: 'yellow'},
{id: 4, color: 'green'}, {id: 5, color: 'blue'} ];
for (var item in arr) {
    console.log(arr[item].color)    
}
// 输出: 'red', 'orange', 'yellow', 'green', 'blue'
复制代码

` 这样看,彷佛以为没有什么毛病,那么在请看下面的代码,仍然是上面这个数组数组

`浏览器

Array.prototype.test = '测试数组';
for (var item in arr) {
    console.log(arr[item].color)    
}
// 输出: 'red', 'orange', 'yellow', 'green', 'blue', '测试数组'
复制代码

` 你们是否是很惊奇的发现,竟然把咱们刚定义在原型链的test给输出来了,这样明显不是咱们想要的,经过这一点其实就已经说明,for in不适合对数组循环操做,由于for in会把数组原型上的可枚举属性给遍历出来,固然你能够经过hasOwnProperty()方法来判断性能优化

`数据结构

for (var item in arr) {
        if (arr.hasOwnProperty(item)) {
            console.log(arr[item].color) 
        }
    }
// 输出: 'red', 'orange', 'yellow', 'green', 'blue'`
复制代码

虽然你这样作能够,可是请明白一点,hasOwnProperty()方法是用来检测当前项是否是实例自己的私有属性的,for in循环始终都会去遍历数组原型上的可枚举对象,这样对于js的性能优化来讲是很是不利的。不只如此,for in的变量item,是字符数据类型,不能直接进行一些数学计算,即便你要操做,你也又会多写一些代码来处理,这样就大大的增长了浏览器对js代码解析的成本了。因此for in更可能是使用在object对象的循环上,for in总结下面几点:函数

  • 一.for in循环不适用对数组的循环,由于for in会去遍历原型上的全部可枚举对象,对性能形成极大负担;
  • 二.for in循环可使用break中断循环,不可使用return返回语句;
  • 三.for in循环的变量item是是循环的key值,字符串数据类型;
  • 四.for in 适合循环object对象数据。

for of循环性能

for of是es6提出的一个新的循环方法,也是本次讲解数组循环里惟一介绍的一个es6的方法。for of 语句建立一个循环来迭代可迭代的对象。在 ES6 中引入的 for of 循环,以替代 for in 和 forEach() ,并支持新的迭代协议。for of 容许你遍历 Arrays(数组), Strings(字符串), Maps(映射), Sets(集合)等可迭代的数据结构等。

`

Array.prototype.test = '测试数组';
var arr = [{id: 1, color: 'red'}, {id: 2, color: 'orange'}, {id: 3, color: 'yellow'},
{id: 4, color: 'green'}, {id: 5, color: 'blue'} ];
for (var item of arr) {
    console.log(item.color)    
}
// 输出: 'red', 'orange', 'yellow', 'green', 'blue'

var str = 'ABCDEFG';
for (var cur of str) {
    console.log(cur)
}
// 输出:A, B, C, D, E, F, G
复制代码

` 看到这里,咱们先抛开for of自己的工做机制,咱们先来瞅瞅它for in比有哪些不一样与优点:

  • 一. for of能够在循环的过程当中使用break中断循环,可是你会说,for in也可使用breack中断循环呀;
  • 二. for of不会去遍历实例原型上的私有属性,这点很重要哦;
  • 三. for of循环里的变量item就是数组元素当前项自己;
  • 四. for of不适合遍历object对象,若是非要使用,你须要结合Object.keys()来使用,否则确定会报错*** is not iterable(不是可迭代的)。
  • 五. for of也不可使用return返回语句,若是不幸你使用了,确定会看到Illegal return statement(非法返回语句);

OK,咱们接下来简单聊聊什么是iterable,可迭代的数据对象,for of循环首先调用集合的Symbol.iterator方法,紧接着返回一个新的迭代器对象。迭代器对象能够是任意具备.next()方法的对象;for of循环将重复调用这个方法,每次循环时调用一次。请看下面例子:

`

var iterable = {
  [Symbol.iterator]() {
    return {
      i: 0,
      next() {
        if (this.i < 3) {
          return { value: this.i++, done: false };
        }
        return { value: undefined, done: true };
      }
    };
  }
};

for (var value of iterable) {
  console.log(value);
}   //输出 0, 1, 2
复制代码

` 总结,for in更多适用object循环使用,for of更适用数组和类数组的使用。更多的for of循环的认识,能够到MDN 去查看和学习。

forEach()循环

forEach()是javaScript数组里的内置一个循环方法,在jQuery里有一个相似的方法each(),本章节不会讲jQuery里的each()。forEach()接受一个回调函数,回调函数接受三个参数forEach(function(item, index, ary){}), item是数组元素当前项,index是当前项的索引值,ary是循环数组的自己,下面看代码示例: `

var arr = [{id: 1, color: 'red'}, {id: 2, color: 'orange'}, {id: 3, color: 'yellow'},
{id: 4, color: 'green'}, {id: 5, color: 'blue'} ];
arr.forEach((item, index, ary) => {
    console.log(item.color);
    console.log(index);
    console.log(ary);
})
// 输出: 'red', 'orange', 'yellow', 'green', 'blue';
// 输出: 0, 1, 2, 3, 4
// 输出: 5次:Array(5)
复制代码

` forEach()循环的使用须要了解的特色就是:

  • 一.回调函数里的三个参数,各自是谁;
  • 二.另外还有一点很是重要,也不能够break中断循环哦。若是你使用了break,确定会提示报错:Illegal break statement(非法中断语句)。
  • 三.forEach()不能够return跳出循环,而你要是使用了return,则更坑,浏览器即不会提示报错,它还会把循环执行完,你要是不了解这个特色,你会蒙蔽的不知道咋回事。

map()循环

map()也是javaScript数组里的内置方法,map()同forEach()同样,接受一个回调函数,回调函数接受三个参数数map(function(item, index, ary){}), item是数组元素当前项,index是当前项的索引值,ary是循环数组的自己,下面看代码示例: `

var arr = [{id: 1, color: 'red'}, {id: 2, color: 'orange'}, {id: 3, color: 'yellow'},
{id: 4, color: 'green'}, {id: 5, color: 'blue'} ];
arr.map((item, index, ary) => {
    console.log(item.color);
    console.log(index);
    console.log(ary);
})
// 输出: 'red', 'orange', 'yellow', 'green', 'blue';
// 输出: 0, 1, 2, 3, 4
// 输出: 5次:Array(5)
复制代码

` 这里的输出和forEach如出一辙,没有任何差异,那么问题来了,ECMAScript组织傻吗,干吗发布两个如出一辙的方法呢,no,他们不傻,由于forEach()和map()确定有差异,看例子:

`

var ary = arr.map((item, index) => {
    return item.page
})
console.log(ary)
// 输出新数组: ['red', 'orange', 'yellow', 'green', 'blue']
复制代码

`

这个例子里返回的这个新数组是不会影响原数组的,并且这个返回的机制,对于结合indexOf(),includes()数组查询的操做很是有用。固然map也是不能够在循环体里使用break;所以map能够总结两点对它的认识:

  • 一.可使用return,return出来的是一个新数组,新数组不影响原数组;
  • 二.不可使用break。

some()循环

some()也是javaScript数组里的内置方法,和前面的forEach,map同样接收一个回调函数,回调函数里默认三个参数,参数顺序一样是 item, index, arr(原数组);下面看例子: `

var arr = [{id: 1, color: 'red'}, {id: 2, color: 'orange'}, {id: 3, color: 'yellow'},
{id: 4, color: 'green'}, {id: 5, color: 'blue'} ];
arr.some(function(){
    console.log(arguments)
})  // 会输出6次 Arguments(3)
arr.some(function(item, index){
    if (index == 4) {
        break;
    }
    console.log(item.color)
    }
)   // 不会输出,会报错Illegal break statement(非法中断语句)

var bool1 = arr.some(function(item, index){
    console.log(item.color) //输出 'red', 'orange', 'yellow', 'green', 'blue'
})  
console.log(bool1)   //输出 fasle

var bool2 = arr.some(function(item, index){
    if (index == 4) {
        return true
    }
    console.log(item.color) //输出 'red', 'orange', 'yellow', 'green'
})  
console.log(bool2)   //输出 true

var bool3 = arr.some(function(item, index){
    if (index == 4) {
        return false
    }
    console.log(item.color) //输出 'red', 'orange', 'yellow', 'green'
})  
console.log(bool3)   //输出 false

var bool4 = arr.some(function(item, index){
    if (index == 4) {
        return ''   //这里返回值只会返回布尔值,若是你给的返回值不是布尔值,则会给你转换成布尔值
    }
    console.log(item.color) //输出 'red', 'orange', 'yellow', 'green'
})  
console.log(bool4)   //输出 false
复制代码

` 经过上面的代码演示,对some方法作以下总结:

  • 一.some方法接收一个回调函数,回调函数接收三个参数,item, index, arr(原数组)
  • 二.some方法不可使用break语句中断循环;
  • 三.some方法可使用return语句跳出循环,some接收一个返回值,返回值是布尔值,默认false,return返回时能够主动返回一个true或者false时的布尔,若是返回其余数据类型会转换成布尔值。

every()循环

every()也是javaScript数组里的内置方法,是和上面的some方法很是相似的一个方法,就像是forEach与map的关系同样,every与some很是类似,可是它们仍是有差异,下面看代码: `

var arr = [{id: 1, color: 'red'}, {id: 2, color: 'orange'}, {id: 3, color: 'yellow'},
{id: 4, color: 'green'}, {id: 5, color: 'blue'} ];
arr.every(function(){
    console.log(arguments)
})  // 会输出1次 Arguments(3)
arr.every(function(item, index){
    if (index == 4) {
        break;
    }
    console.log(item.color)
    }
)   // 不会输出,会报错Illegal break statement(非法中断语句)
var bool1 = arr.every(function(item, index){
    console.log(item.color) //输出 'red'
})  
console.log(bool1)   //输出 fasle

var bool2 = arr.every(function(item, index){
    if (index == 4) {
        return true
    }
    console.log(item.color) //输出 'red'
})  
console.log(bool2)   //输出 false
复制代码

` 到这里,就已经能够总结出every来了,说实话,我本身我的是十分不理解这个方法存在的意义,看下面几点总结:

  • 一.every方法接收一个回调函数,回调函数接收三个参数,item, index, arr(原数组)
  • 二.every方法不可使用break语句中断循环;
  • 三.every方法不能循环完整个数组,它只能遍历到数组的第一个当前项,every一样接收一个布尔的返回值,这个值就是固定的false。

filter()循环

filter()也是javaScript数组里的内置方法,filter方法,语义上是过滤器,数组的过滤器,经过循环遍历,而后根据条件来返回本身须要的数组当前项,filter是个使用很是频繁的数组方法之一,下面咱们看代码例子: `

var arr = [{id: 1, color: 'red'}, {id: 2, color: 'orange'}, {id: 3, color: 'yellow'},
{id: 4, color: 'green'}, {id: 5, color: 'blue'} ];
var ary = arr.filter(function(item, index){
    console.log(arguments)  // arguments包含三个默认参数,item,index,以及原数组
    console.log(item.color); //输出'red', 'orange', 'yellow', 'green', 'blue'
    if (index > 1 && index < 4) {
        return item
    }
   
})
console.log(ary)    //输出[ {id: 2, color: 'orange'}, {id: 3, color: 'yellow'},
{id: 4, color: 'green'}]
复制代码

` 经过代码演示,咱们发现filter和前面的全部数组方法同样,接收一个回调函数,回调函数默认三个参数,filter能够接收返回值,返回值默认以一个新数组接收,filter使用return不会跳出循环,下面咱们对filter作个总结:

  • 一. filter接收一个回调函数,回调函数默认三个参数,item, index, arr(原数组)
  • 二. filter接收一个返回值,返回值是个新数组,新数组不影响原数组,
  • 三. filter里的return是返回知足本身条件的当前项的,不能够跳出训话,
  • 四. filter里不可使用break中断语句;

最后总结

在本次分享里面,还有好几个能够循环数组的方式没有介绍到,有es6标准里的三个新方法keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历,这个下次分享es6时在补充介绍了。而在本次的分享里面,filter,some,every我我的认为它们不是真正意义上的循环方法,它们都是为了作特定需求数组处理的,只是它们在功能上面具有了对数组遍历的能力。而咱们在对数组作循环处理的时候,我我的推荐使用for循环, for of循环,map(),forEach()这几个为主。本次分享就到这里,谢谢!

相关文章
相关标签/搜索