一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第9天,点击查看活动详情。
前言
我们从解决下面问题来区分for,forEach,for of,for in:
如何遍历数字下标的数组或类数组对象?
比如有两个需求:
- 用一组索引数组实现课程表;
- 定义函数实现计算任意多个数的和;
普通for循环
需求一:课程表--可以实现;
var arr = ['语文', '英语', '数学', '体育', '音乐', '美术', '化学'];
for (var i = 0; i < arr.length; i++) {
console.log(`第${i+1}节课是:${arr[i]}`);
}
需求二:定义函数实现计算任意多个数的和--可以实现;
function add() {
//arguments[ ]
var result = 0;
for (var i = 0; i < arguments.length; i++) {
result += arguments[i];
}
return result;
}
console.log(add(1,2,3)); //6
console.log(add(1,2,3,5)); //11
普通for循环的优缺点
优点:既可以遍历索引数组,又可以遍历类数组对象(arguments),只要下标是数字;
缺点:没有可简化的空间;
forEach
没有返回值,不改变原数组
var arr=['语文','英语','数学','体育','音乐','美术','化学'];
arr.forEach(function(name,index){
console.log(`第${index + 1}节课是:${name}`)
})
可更简化:
var arr=['语文','英语','数学','体育','音乐','美术','化学'];
arr.forEach((name,index)=> {
console.log(`第${index + 1}节课是:${name}`)
})
需求二:定义函数实现计算任意多个数的和--无法实现;
function add() {
//arguments[ ]
var result = 0;
//这里会报错,arguments.forEach is not function
arguments.forEach((m)=>{
result += m;
})
return result;
}
console.log(add(1,2,3)); //6
console.log(add(1,2,3,5)); //11
这里会报错,arguments.forEach is not function;
因为:forEach是个数组类型函数,但arguments不是数组类型对象,所以无权使用数组类型函数;
forEach优缺点
优点:可以配合es6的箭头函数,简化代码;
缺点:只能遍历数组下标的索引数组,无法遍历类数组对象;
解决:
使用for of
for of
es6新增的特性,for...of可以循环读取键值,如果要通过for...of循环,获取数组的索引,可以借助数组实例的entries方法和keys方法
for(var 元素值m of 索引数组/类数组对象){
//of会依次取出索引数组/类数组对象中每个属性值
//自动保存在of前的变量中
}
需求一:
for(var [index,name] of arr.entries()){
console.log(`第${index + 1}节课是:${name}`)
}
var fruits = ["Banana", "Orange", "Apple", "Mango"];
var x = fruits.entries();
console.log(x.next().value)
//[0, 'Banana']
var fruits = ["Banana", "Orange", "Apple", "Mango"];
var x = Object.entries(fruits);
console.log(x)
//[['0', 'Banana'], ['1', 'Orange'], ['2', 'Apple'], ['3', 'Mango']]
需求二:
function add() {
//arguments[ ]
var result = 0;
for(var m of arguments){
result += m;
}
return result;
}
console.log(add(1,2,3)); //6
console.log(add(1,2,3,5)); //11
for of的问题
- 无法获得下标位置i,只能获得元素值,对于数组借助
entries方法和keys方法只返回数字索引的属性,对于类数组对象,因为不能使用;
function add() {
//arguments[ ]
var result = 0;
for(var [index,m] of arguments.entries()){
result += m;
}
return result;
}
console.log(add(1,2,3)); //6
console.log(add(1,2,3,5)); //11
会报错,因为entries是数组的实例方法;
- 无法控制遍历的顺序或步调,只能从头到尾,一个挨一个的顺序遍历;
- 无法遍历下标名为自定义的对象和关联数组;
但是:
因为数组绝大多数都是数字下标,绝大多数也是从头到尾一个挨着一个遍历的,且绝大多数循环不太关心下标位置,之关心元素值,所以for of用的还是比较多的。
for in
JavaScript原有的for...in循环。
let arr = [3, 5, 7];
arr.foo = 'hello';
for (let i in arr) {
console.log(i); // "0", "1", "2", "foo"
}
for (let i of arr) {
console.log(i); // "3", "5", "7"
}
上面的官方例子就可以看出for of和for in的区别;
上面代码中,for...of循环不会返回数组arr的foo属性,而for in可以,并且for...in,只能获得对象的键名,不能直接获取键值,而ES6提供for...of循环,允许遍历获得键值。
总结for,forEach,for of,for in的区别
总结:
- 下标为数字,首选for of;
- 下标为自定义字符串,首选for in;