17年5月更js中的for循环

xiaoxiao2021-02-28  129

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

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

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

普通的for循环for…inforEach迭代

在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好在哪里吧:

不仅支持遍历数组,还可以遍历字符串,类数组对象,Map,Set等。避开了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靠谱。

转载请注明原文地址: https://www.6miu.com/read-26307.html

最新回复(0)