你不知道的for-in和for-of

你不知道的for-in和for-of_第1张图片

1.for-in

for-in是for循环的一个变体,它可以把一个对象的所有属性依次遍历出来,如:

var o = {
    name: 'Jack',
    age: 20,
    city: 'Beijing'
};
for (var key in o) {
    alert(key); // 'name', 'age', 'city'
}
var a = ['A', 'B', 'C'];
for (var i in a) {
    alert(i); // '0', '1', '2' 注意,这里的得到的结果是srting
    alert(a[i]); // 'A', 'B', 'C'
}

2.for-of

for-of是ES6引入的新语法,谈到for-of,就先来谈谈ES6引入的新类型iterable,因为只有具有iterable类型的集合才可以通过新的for ... of循环来遍历。

Array、Map和Set都属于iterable类型

Map类型
Map是一组键值对的结构,具有极快的查找速度。
举个例子,假设要根据同学的名字查找对应的成绩,如果用Array实现,需要两个Array:

var names = ['Michael', 'Bob', 'Tracy'];
var scores = [95, 75, 85];

给定一个名字,要查找对应的成绩,就先要在names中找到对应的位置,再从scores取出对应的成绩,Array越长,耗时越长。
如果用Map实现,只需要一个“名字”-“成绩”的对照表,直接根据名字查找成绩,无论这个表有多大,查找速度都不会变慢。用JavaScript写一个Map如下:

var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);
m.get('Michael'); // 95

Set类型
Set和Map类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在Set中,没有重复的key。
重复元素在Set中自动被过滤:



var s = new Set([1, 2, 3, 3, '3']);
s; // Set {1, 2, 3, "3"}

3.for ... of循环和for ... in循环有何区别?

for ... in循环由于历史遗留问题,它遍历的实际上是对象的属性名称。一个Array数组实际上也是一个对象,它的每个元素的索引被视为一个属性。

当我们手动给Array对象添加了额外的属性后,for ... in循环仍然会去遍历这个新的属性:

var a = ['A', 'B', 'C'];
a.name = 'Hello';
for (var x in a) {
    alert(x); // '0', '1', '2', 'name'
}

但是for...of只会循环集合的本身

var a = ['A', 'B', 'C'];
a.name = 'Hello';
for (var x of a ) {
    alert(x); // 'A', 'B', 'C'

}

另外从返回结果来看,一个返回对象属性的值,一个返回对象的元素。
4.最好的解决方案
iterable有个内置方法:forEach,它接受一个匿名函数,每次迭代就自动回调该函数。
以array为例子:

var a = ['A', 'B', 'C'];
a.forEach(function (element, index, array) {
    // element: 指向当前元素的值
    // index: 指向当前索引
    // array: 指向Array对象本身
    alert(element);
});

以Set为例子,Set没有索引,所以前两个参数都是元素本身

var s = new Set(['A', 'B', 'C']);
s.forEach(function (element, sameElement, set) {
    alert(element);
})

以Map为例子,Map的回调函数参数依次为value、key和map本身:

var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
m.forEach(function (value, key, map) {
    alert(value);
});

你可能感兴趣的:(你不知道的for-in和for-of)