自己写了一些简单的例子,将 for...of 和 for...in 进行对比,以加深理解。
目录
一、代码示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>遍历</title>
</head>
<body>
<script>
let newArray = [1, 2, 3, 4, 5];
let objArray = [{isChanged: false},{isChanged: false}];
newArray.name = '数组';
let obj = {name: 'Jon', age: 22, home: 'xxx'};
let set = new Set([1, 2, 3, 4, 5]);
let map = new Map([['A', 1], ['B', 2], ['C', 3]]);
// for...of 测试
let testForOf = function () {
// 1. 普通数组测试
for(let item of newArray){
item = 0; // 这里不会改变原数组
console.log(typeof item, item); // item 为 数组元素的值 ,但只会输出 1, 2, 3, 4, 5,但这里不会输出 name 数组
}
console.log(newArray); // [1, 2, 3, 4, 5, name: '数组'] ,观察原数组是否改变,结果没用改变
// 2. 对象数组测试
for(let item of objArray){
item.isChanged = true; // 这里会改变原数组
}
console.log(objArray); // [{isChanged: true},{isChanged: true}] 可以看到原数组发生了改变,在是否改变原数组方面,这点和 forEach 以及 map 类似
// 3. for of 遍历普通对象会报错
// 4. 遍历可迭代对象,这里以 Set 和 Map 为例
for(let item of map){
console.log(item); // ['A', 1]['B', 2]['C', 3]
}
for(let item of set){
console.log(item, typeof item); // 1, 2, 3, 4, 5 item 类型为 number
}
}
// for...in 测试
let testForIn = function () {
// 1. 数组测试
for(let item in newArray){
newArray[item] = 0; // 这里会改变原数组
console.log(typeof item, item, newArray[item]); // item 为 string 类型,它是数组元素的键
}
console.log(newArray); // [0, 0, 0, 0, 0, name: 0] ,观察原数组是否改变,原数组发生改变
// 2. 对象测试
for(let item in obj){
console.log(typeof item, item, obj[item]); // item 为 string 类型,它是数组元素的键,且这里会输出前面自定义的可枚举属性 name
}
// 3. 对象数组测试
for(let item in objArray){
objArray[item].isChanged = true; // 这里通过键值访问到对应的某一项,然后也会改变原数组
}
console.log(objArray); // [{isChanged: true},{isChanged: true}] 可以看到原数组发生了改变,在是否改变原数组方面,这点和 forEach 以及 map 类似
// 4. 是否查找原型链测试
function Parent(){
this.name = 'parent';
this.age = 70;
}
function Child(){
this.myName = 'child';
this.myAge = 35;
}
Child.prototype = new Parent(); // 通过原型链继承
let child = new Child();
for(let item in child){
console.log(item, child[item]); // myName myAge name age 均会输出,即会查找原型链
}
// 5. 遍历可迭代对象,这里以 Set 和 Map 为例
for(let item of map){
console.log(item); // ['A', 1]['B', 2]['C', 3]
}
for(let item of set){
console.log(item, typeof item); // 1, 2, 3, 4, 5 item 类型为 number
}
}
// 测试函数调用
// testForOf();
// testForIn();
</script>
</body>
</html>
二、for...of 与 for...in 总结
for...of
- es6新增,可遍历数组(只要内部有迭代器的实现均可遍历,包括Map和Set等,是否实现了迭代器与是否具有 length 属性无关),不能遍历普通对象。
- 它是按值来进行遍历的,item 为每一项数组元素的值。
- for...of 只会保证数组中元素的首地址不会改变,但该地址所指向的值可以改变(一般是引用类型数据)。
for...in
- 常用于遍历对象,也可用于遍历数组(尽量不要它遍历数组,可能不会按照数组的顺序遍历,容易造成错误)。
- 它是按键来进行遍历的,item 为 每一个键值对的键,它遍历对象的可枚举属性,包括一些自定义的可枚举属性等,还会查找原型链。
- for...in 通过键值来访问数组元素,不管元素是什么类型,可以通过键值直接改变原数组(如:arr[x] = xxx)。
for...of 与 for...in 都能正确响应 break,continue以及return,但 forEach,map 不能正确响应 break 和 continue。
关于 forEach 和 map 的介绍可参考我的另一篇文章 forEach 和 map 会不会改变原数组 。

5万+

被折叠的 条评论
为什么被折叠?



