参考:
全面解析JavaScript里的循环方法之forEach,for-in,for-of
常规for
for循环较为灵活,因为起始索引、条件可以都可以自定义。
缺点是书写较麻烦,获取数组长度来循环。
let arr = [];
for(let i=0;i<10000000;i++){
arr[i] = i;
}
let startTime = egret.getTimer();
let sum:number = 0;
for(let i=0;i<10000000;i++){
sum += arr[i];
}
console.log(sum);
console.log(egret.getTimer() - startTime); //240ms - 380ms
for循环还能多条件判断
for(let i=0,j<10;i<10&&j<20;i++,j++){
}
for-each
foeach适用于遍历数组,减少了获取数组长度的麻烦。
缺点不能中途跳出循环,不够灵活。
let arr = [];
for(let i=0;i<10000000;i++){
arr[i] = i;
}
let startTime = egret.getTimer();
let sum:number= 0;
arr.forEach((value, index)=>{
sum += value;
});
console.log(sum);
console.log(egret.getTimer() - startTime); //300ms-440ms
foreach还有两个参数,arr是数组元素本身,this是传递this关键字
let arr = [1,2,3];
arr.forEach((value,index,arr)=>{
console.log(arr);
console.log(this);
}, this)

forEach循环无法跳出,无法使用break。
如下所示,尝试break,提示报错;尝试return跳出循环,但是输出值仍然是2,5。
let arr = [1,2,3,4];
arr.forEach((value,index)=>{
//尝试打断循环,仅仅能跳过value=1这一次循环而已,不能跳出forEach整个循环
if(value == 1){
return;
}
//尝试修改数组,可以修改
arr[2] = 5;
//尝试对数组进行删除操作,可以删除
arr.splice(3,1);
console.log(value); //2,5
})
console.log(arr); // [1,2,5]
在函数中对数组进行移除操作,遍历索引0时输出1,然后移除了1,数组变成[2,3],那么遍历索引1时输出3。
所以在遍历中需要进行数组删除元素操作,需要逆序进行,但是forEach没法逆序遍历,得用for(let i=len-1,i>=0;i--)去逆序遍历。
let list = [1,2,3];
list.forEach((item,index,arr)=>{
console.log(item); //输出1,3
arr.splice(0,1)
})
for-in
从效率来看基本放弃常规数组操作了。
主要用于遍历object
let arr = [];
for(let i=0;i<10000000;i++){
arr[i] = i;
}
let startTime = egret.getTimer();
let sum:number= 0;
for(let key in arr){
sum += arr[key];
}
console.log(sum);
console.log(egret.getTimer() - startTime); //1600ms - 2000ms
遍历object
let obj = {"name":"peter", "age":23};
for(let key in obj){
console.log(key, obj[key]); //name peter, age 23
}
那么这个遍历是顺序的吗?不是顺序的 具体参考:js能够保证object属性的输出顺序吗
for-of
for-of是新特性,和for-in的区别是,for-of是获取键值,for-in是获取键名。
let arr = [];
for(let i=0;i<10000000;i++){
arr[i] = i;
}
let startTime = egret.getTimer();
let sum:number= 0;
for(let value of arr){
sum += value;
}
console.log(sum);
console.log(egret.getTimer() - startTime); //250ms - 380ms
for-of中可以修改数组,也可以跳出循环。
for-of获取的键值,for-in获取的是键名。
for-of不能遍历object,for-in可以。
let arr = [1,2,3,4];
for(let value of arr){
//尝试修改数组,可以修改
arr[1] = 5;
//尝试删除数组值3,但是不知道值3的索引是多少...
if(value == 3){
//arr.splice(i,3);
}
//尝试跳出循环,可以跳出
if(value == 3){
break;
}
console.log(value); //1,5
}
console.log(arr); //[1,5,3,4]
因为for-of不能获取索引,在es6中进行了扩展,参考:数组的扩展
let arr:Array<number> = [1,2,3,4];
for(let key of arr.keys()){ //报错,Egret中还不能用哎,新特性,只能ES6
console.log(key);
}
for-of中使用splice
let list = [1,2,3,4,5];
for(let value of list){
if(value == 2){
let index = list.indexOf(value);
if(index != -1){
list.splice(index,1);
}
}else{
console.log(value); //1,4,5
}
}
在删除2以后,数组变成了[1,3,4,5] ,原本访问[1,2,3,4,5]中的3的索引位置,变成了4。 所以输出是1,4,5。
假如数组中的不是12345,而是5个需要操作的对象,那么3这个对象就被跳过了操作。
所在在有移除操作的遍历中,不能使用for-of,而是要使用逆循环。
let list = [1,2,3,4,5];
let len = list.length;
for(let i=len-1;i>=0;i--){
if(list[i]==2){
let index = list.indexOf(2);
list.splice(index,1);
}else{
console.log(list[i]); //5,4,3,1
}
}
这样3这个位置的对象,也会被进行输出操作,而不是被跳过。
map
map()方法创建一个新数组,其结果是在调用数组中的每个元素上调用一个提供的函数
var numbers = [1, 5, 10, 15];
var doubles = numbers.map(function(x) {
return x * 2;
});
// doubles is now [2, 10, 20, 30]
// numbers is still [1, 5, 10, 15]
var numbers = [1, 4, 9];
var roots = numbers.map(Math.sqrt);
// roots is now [1, 2, 3]
// numbers is still [1, 4, 9]
浙公网安备 33010602011771号