1 for
最简单的一种循环遍历方法,也是使用频率最高的一种,可优化
循环过程中支持修改索引(修改 i)
在这里插入代码片// for 最简单的一种循环遍历方法,循环过程中支持修改索引(修改i)
console.log('1 for循环')
let arr = [1,2,3,4,5]
for(var i=0;i<arr.length;i++){
console.log(arr[i])
if(i==0){
i=3
}
}
优化:使用临时变量,将长度缓存起来,避免重复获取数组长度,当数组较大时优化效果才会比较明显
// // 优化:使用临时变量,将长度缓存起来,避免重复获取数组长度,当数组较大时优化效果才会比较明显
let arr1 = Array.from(new Array(10000), (x, index)=>{
return index
})
// var len = arr1.length
let start = new Date().getTime()
console.log('1 for start',start)
for(var i = 0; i < arr1.length; i++) {
console.log(`for循环${arr1.length}个数据`)
}
let end = new Date().getTime()
console.log('1 for end', end)
console.log('耗时', end - start)
下面我们把arr1的长度先取出来,在看看执行时间
// // 优化:使用临时变量,将长度缓存起来,避免重复获取数组长度,当数组较大时优化效果才会比较明显
let arr1 = Array.from(new Array(10000), (x, index)=>{
return index
})
var len = arr1.length
let start = new Date().getTime()
console.log('1 for start',start)
for(var i = 0; i < len; i++) {
console.log(`for循环${len}个数据`)
}
let end = new Date().getTime()
console.log('1 for end', end)
console.log('耗时', end - start)
明显耗时比上面没提前把长度取出来的少
2 for…in…
这个循环用的人也很多(输出的 key 是数组索引),如果遍历的是对象,输出的则是对象的属性名
console.log("====================for in 的使用")
let arr1 = Array.from(new Array(10000), (x, index)=>{
return index
})
var len = arr1.length
let forInStart = new Date().getTime()
console.log('1 for in start',forInStart)
for(let key in arr1){
console.log(`for in 循环${len}个数据`)
}
let forInEnd = new Date().getTime()
console.log('1 for in end', forInEnd)
console.log('耗时', forInEnd - forInStart)
如果是对象取到key值
let obj = {
a: 11,
b: 22,
c: 33
}
for(let key in obj) {
console.log(key)
}
// a b c
3 for…of…
注意:不能循环对象,因为任何数据结构只要部署 Iterator接口,就可以完成遍历操作,有些数据结构原生具备 Iterator 接口,比如Array、Map、Set、String等,而 Iterator 接口是部署在数据结构的Symbol.iterator属性上的,而对象Object恰恰是没有Symbol.iterator属性的,所以无法被for…of遍历
// for…of… 注意:不能循环对象,因为任何数据结构只要部署 Iterator接口,就可以完成遍历操作,有些数据结构原生具备 Iterator 接口,比如Array、Map、Set、String等,而 Iterator 接口是部署在数据结构的Symbol.iterator属性上的,而对象Object恰恰是没有Symbol.iterator属性的,所以无法被for..of遍历
console.log("====================for of 的使用")
let arr1 = Array.from(new Array(10000), (x, index)=>{
return index
})
var len = arr1.length
let start = new Date().getTime()
console.log('1 for in start',start)
for(let key of arr1){
console.log(`for of 循环${len}个数据`)
}
let end = new Date().getTime()
console.log('1 for in end', end)
console.log('耗时', end - start)
4 forEach(也叫作增强for循环)
- 数组里的元素个数有几个,该方法里的回调就会执行几次
- 第一个参数是数组里的元素,第二个参数为数组里元素的索引,第三个参数则是它自己(利用第三个参数可以进行数组去重)
- 数组自带的遍历方法,foreach在循环次数未知或者计算起来较复杂的情况下效率比for循环高
- 循环的数组元素是基本数据类型,不会改变原数据的数据,循环的数组元素为对象,会改变原数组的对象属性的值
- 循环过程中不支持修改索引,回调中使用return不会报错,但是无效
注意:不能使用break和continue跳出整个循环或当前循环的,会报错,但是结合try…catch可以实现跳出循环
console.log("====================forEach的使用")
let arr1 = Array.from(new Array(10000), (x, index)=>{
return index
})
var len = arr1.length
let start = new Date().getTime()
console.log('1 for in start',start)
arr1.forEach((item,index,array)=>{
console.log(`for of 循环${len}个数据`)
})
let end = new Date().getTime()
console.log('1 for in end', end)
console.log('耗时', end - start)
使用try…catch…可以跳出循环
// 使用try...catch...可以跳出循环
try {
let arr = [1, 2, 3, 4];
arr.forEach((item) => {
// 跳出条件
if (item === 3) {
throw new Error("LoopTerminates");
}
console.log(item);
});
} catch (e) {
if (e.message !== "LoopTerminates") throw e;
};
5 map
map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
map() 方法按照原始数组元素顺序依次处理元素。
注意: map() 不会对空数组进行检测。
注意: map() 不会改变原始数组。
注意:不能使用break和continue跳出整个循环或当前循环的,会报错,但是结合try…catch可以实现跳出循环
console.log("====================map的使用")
let arr1 = Array.from(new Array(10000), (x, index)=>{
return index
})
var len = arr1.length
let start = new Date().getTime()
console.log('1 map start',start)
arr1.map((item,index,array)=>{
console.log(`map 循环${len}个数据`)
})
let end = new Date().getTime()
console.log('1 map end', end)
console.log('耗时', end - start)
map会改变原数组对象里面的属性
// 二、会改变原数组元素中对象的属性值
var arr = [{a: 1, b: 2},{a: 11, b: 12}]
let newARR = arr.map((item)=>{
item.b = 111
return item
})
console.log('arr数组',arr) // [{a: 1, b: 111},{a: 11, b: 111}]
console.log('newARR',newARR) // [{a: 1, b: 111},{a: 11, b: 111}]
如果使用return不会改变原数组里面的属性
var arr = [{a: 1, b: 2},{a: 11, b: 12}]
let newARR = arr.map((item)=>{
return {
...item,
b:111
}
})
console.log('arr数组',arr) // [{a: 1, b: 2},{a: 11, b: 12}]
console.log('newARR',newARR) // [{a: 1, b: 111},{a: 11, b: 111}]
使用try…catch…可以跳出循环
try {
var arr = [1, 2, 3, 4];
arr.map((item) => {
//跳出条件
if (item === 3) {
throw new Error("LoopTerminates");
}
console.log(item);
return item
});
} catch (e) {
if (e.message !== "LoopTerminates") throw e;
};
6 filter(ES6)
遍历数组,过滤出符合条件的元素并返回一个新数组
console.log("====================filter的使用")
var arr = [
{ id: 1, name: '买笔', done: true },
{ id: 2, name: '买笔记本', done: true },
{ id: 3, name: '练字', done: false }
]
var newArr = arr.filter(function (item, index) {
return item.done
})
console.log(newArr)
let arr1 = Array.from(new Array(10000), (x, index)=>{
return index
})
var len = arr1.length
let start = new Date().getTime()
console.log('1 map start',start)
arr1.filter((item,index,array)=>{
console.log(`map 循环${len}个数据`)
})
let end = new Date().getTime()
console.log('1 map end', end)
console.log('耗时', end - start)
7 some(ES6)
遍历数组,只要有一个以上的元素满足条件就返回 true,否则返回 false
console.log("====================some的使用")
var arr = [
{ id: 1, name: '买笔', done: true },
{ id: 2, name: '买笔记本', done: true },
{ id: 3, name: '练字', done: false }
]
var bool = arr.some(function (item, index) {
return item.done
})
console.log(bool) // true
8 every(ES6)
遍历数组,每一个元素都满足条件 则返回 true,否则返回 false
var arr = [
{ id: 1, name: '买笔', done: true },
{ id: 2, name: '买笔记本', done: true },
{ id: 3, name: '练字', done: false }
]
var bool = arr.every(function (item, index) {
return item.done
})
console.log(bool) // false
9 find(ES6)
遍历数组,返回符合条件的第一个元素,如果没有符合条件的元素则返回 undefined
var arr = [1, 1, 2, 2, 3, 3, 4, 5, 6]
var num = arr.find(function (item, index) {
return item === 3
})
console.log(num) // 3
10 findIndex(ES6)
遍历数组,返回符合条件的第一个元素的索引,如果没有符合条件的元素则返回 -1
var arr = [1, 1, 2, 2, 3, 3, 4, 5, 6]
var num = arr.findIndex(function (item) {
return item === 3
})
console.log(num) // 4
总结,其实按照一万条数据来看,好像效率不是差别很大