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 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 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比有哪些不一样与优点:
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()循环的使用须要了解的特色就是:
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能够总结两点对它的认识:
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方法作以下总结:
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来了,说实话,我本身我的是十分不理解这个方法存在的意义,看下面几点总结:
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作个总结:
最后总结
在本次分享里面,还有好几个能够循环数组的方式没有介绍到,有es6标准里的三个新方法keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历,这个下次分享es6时在补充介绍了。而在本次的分享里面,filter,some,every我我的认为它们不是真正意义上的循环方法,它们都是为了作特定需求数组处理的,只是它们在功能上面具有了对数组遍历的能力。而咱们在对数组作循环处理的时候,我我的推荐使用for循环, for of循环,map(),forEach()这几个为主。本次分享就到这里,谢谢!