# for in 循环的顺序问题
for in 通常用来循环遍历对象,对象中有多少键值对就循环多少次
顺序问题:首先循环数字的属性名(按照从小到大),然后把剩下的属性名按照写的顺序循环
var obj = {
name: 'newming',
age: 23,
1: 10086
}
for (var key in obj) {
console.log(key);
console.log(obj[key]);//注意获取属性值只能用[key]获取,因为属性名如果是数字的话是无法通过 .key 获取的
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# for...in 与 for...of 的区别
for in 遍历的是key,for of遍历的是value。其中 for in 推荐使用 Object.keys 替代
for of 是基于 iterator 迭代器进行遍历的,返回 value。部分数据结构实现了迭代器的规范 [Symbol.iterator],例如数组、部分类数组、Set、Map
for...in... 返回的是所有能够通过对象访问的、可枚举的(enumerable)属性,包含实例属性和原型上的属性
Object.keys() 方法返回的是一个包含所有可枚举属性的字符串数组。
Object.getOwnPropertyNames() 返回的是一个包含所有实例属性的数组,不论是否可枚举
for in
的缺点:
- for in 迭代顺序依赖于执行环境,不一定保证顺序
- for in 不仅会遍历当前对象,还包括原型链上的可枚举属性,可以配合 Object.hasOwnProperty 解决
- for in 没有break中断
- for in 不适合遍历数组,主要应用为对象
- for in 无法遍历到 Symbol 属性,Object.keys, Object.getOwnPropertyNames也拿不到,可以使用 Object.getOwnPropertySymbols 拿到 Symbol 属性
for of
的优点:
- for of 有与for in 一样的简洁语法(这也是两者容易混乱的点),但没有for in的缺点
- for of 保证顺序且仅遍历当前对象
- for of 可与break,continue,return配合
# 各种循环
# Q1 各种循环性能对比
- 基于var声明的时候,for和while循环性能差不多,不确定循环次数的情况下用while
- 基于let声明的时候,for循环性能更好,原因是: 没有创建全局不释放的变量
- for循环中,用let声明时,性能比var好
- forEach之类的方法性能比 for 循环差
- for in 性能最差,需要遍历它的原型链
- for of 性能比 for in 好点,比 for while 慢
for(let i =0; i< 100000; i++) {}
for(var i =0; i< 100000; i++) {} // 需要创建全局不释放的变量
let i = 0
while(i < 10000) {
// while条件语句中不可以声明变量,只能使用全局变量
i++
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# Symbol.iterator
var arr = [10, 20, 30]
// Symbol.iterator规范:必须具备next属性,执行一次next方法,拿到结构中的一项的值 {done, value}
arr[Symbol.iterator] = function() {
let self = this
let index = 0
return {
next() {
if (index > self.length - 1) {
return {
done: true,
value: undefined
}
}
return {
done: false,
value: arr[index++]
}
}
}
}
for(let val of arr) {
console.log(val)
}
// 实现for of遍历对象
var obj = {
0: 3,
1: 1,
a: 1,
b: 2,
length: 1
}
obj[Symbol.iterator] = Array.prototype[Symbol.iterator]
for(let val of obj) {
console.log(val) // 3
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37