17年5月更 js中的for循环

之前的认识中,没有注意到for-of循环,也没有写foreach循环

现在重新来总结一下js里面关于for循环的用法

在ES5中,关于for循环只有三种:

  • 普通的for循环
  • for…in
  • forEach迭代

在ES6中,新增了一个for循环:

  • for…of

普通的for循环

const arr = [1, 2, 3, 4, 5];
for(let i = 0,len = arr.length; i < len; i++){
    console.log(arr[i]);
}
// 1, 2, 3, 4, 5

for-in

通常情况下,我们很少用for-in来遍历数组,因为for-in遍历的是数组索引。

const arr = [1, 2, 3 ,4 ,5]
for(let v in arr){
    console.log(arr[v]);
}
// 1, 2, 3, 4, 5

不对不对不对!!!!!!!
重要的事情还是说三遍!

经过在MDN上查阅,发现for-in遍历的不是数组的索引,而是遍历可枚举属性。
而数组的索引正是可枚举的整数名,所以我们之前可以使用for-in来遍历数组。
但是for-in 不应该去遍历一个对下标顺序很重要的Array。因此当迭代那些对访问次序重要的Array的时候,我们可以使用forEach和for-of(这两个随后会说)。

但是for-in难道就真的不适合遍历数组了么????

for-in可能在绝大多数的场景上,不如其他循环好用,因为性能差,属性顺序不准确。但是在遍历一些稀疏数组的时候,for-in是绝对好用的。

还是看图吧。

这里写图片描述

这里写图片描述

我们可以很清楚的看到,只有for-in在遍历稀疏数组的时候,只遍历真实存在的值。

所以通常我们仅在遍历对象的时候使用for-in循环。

const obj = {a: 1, b: 2, c: 3};

for(let v in obj){
    console.log(`obj.${v} = ${obj[v]}`);
}
// obj.a = 1
// obj.b = 2
// obj.c = 3

针对所说的for-in遍历的是可枚举属性
那么:在原型上的属性,for-in也是可以遍历的到的。

const obj = {a: 1, b: 2, c: 3};
function Color(){
    this.color = 'red';
}
Color.prototype = obj;
let newObj = new Color;
for(let v in newObj){
    console.log(v);
}
// color, a, b, c

可以看出,for-in是可以对一切可枚举的属性进行遍历的,包括原型链上的属性。但是那么通常我们并不希望获取原型链上的属性。
那么我们可以使用 hasOwnProperty()方法。该方法返回一个布尔值,表示对象是否具有指定的属性作为自身属性。

这样我们可以把之前的例子进行修改:

let obj = {a: 1, b: 2, c: 3};
function Color(){
    this.color = 'red';
}
Color.prototype = obj;
let newObj = new Color();
for(let v in newObj){
    if(newObj.hasOwnProperty(v)){
        console.log(v);
    }
}
// color

eg: 这里要多说一句哦,这个for-in是ES3 就推出的专门来遍历对象属性的,但是发现更多的需求其实是并不需要遍历原型链上的属性,所以ES5就推出了专门来遍历对象上自身属性的方法——Object.keys()

在ES2017中,已经配套的把Object.values和Object.entries来遍历值,和键值。
但是这三个方法返回的都是数组,需要配合for-of循环来使用。

forEach

在ES5中,引入了一个专门迭代Array的方法,即forEach循环。
其实引入了五个,比如:

  • forEach() 对数组中的每一项运行给定函数,没有返回值。
  • filter() 对数组中的每一项运行给定的函数,返回为true的项组成的数组。
  • map() 对数组中的每一项运行给定的函数,返回函数运行后组成的数组。
  • every() 对数组中每一项运行给定函数,若每一项都为true,则返回true。
  • some() 对数组中的每一项运行给定函数,若其中有一项为true,则返回true。

他们都可以传入三个参数,分别是
item,index,array

const arr = [1, 2, 3];
arr.forEach((data) => {
    console.log(data);
})
// 1, 2, 3

for-of

已经有了for-in,for,forEach,为什么要ES6还要搞出来个for-of呢?
这是因为之前的循环,各有各的缺点。
那说说for-of好在哪里吧:

  1. 不仅支持遍历数组,还可以遍历字符串,类数组对象,Map,Set等。
  2. 避开了for-in的各种缺陷。
let arr = [100, 200, 300];
for(let i = 0; i < arr.length; i++){
    console.log(arr[i]);
}
for(let i in arr){
    console.log(arr[i]);
}
for(let i of arr){
    console.log(i);
}

可以看出,使用for-of循环是最简单的。for-in并不可靠。

但是,for-of在遍历普通对象的时候就力不从心了。

let obj = {a: 1, b: 2, c: 3};
for(let i of obj){
    console.log(i);
}
// 报错
for(let i in obj){
    console.log(i);
}
// a, b, c

总结:
for 是只能处理Array,性能好,但是有时候代码量较大。

for-in 为遍历对象而设计,但又能比较好的去处理稀疏数组。在遍历对象的时候却又会遍历到原型链上的属性,所以常常用hasOwnProperty来进行过滤。但现在可以使用Object.keys来替代for-in+hasOwnProperty

forEach 是为迭代Array而设计,对Array中的每一项都运行给定的函数。

for-of 是为了之前的for循环中的弊端所做的补救。for-of规避了for-in的缺点,并且还可以去遍历类数组对象。但是for-of并不能适用于普通对象。对于普通对象,还是使用for-in靠谱。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值