for…in
for…in语句以任意顺序迭代一个
对象
的除Symbol
以外的可枚举
属性,包括继承的可枚举属性。for…in是为遍历对象属性
而构建的
使用:
let obj = {
a: 1,
b: 2,
c: 3,
};
for (let key in obj) {
console.log(key, obj[key]);
}
// 输出: a 1, b 2, c 3
1、任意顺序迭代一个对象
for in也可以迭代数组,因为数组也是一个对象。
不推荐用for...in迭代一个关注索引顺序的Array,因为for...in是以任意顺序迭代的
2、可迭代除Symbol
以外的可枚举
属性
let obj = {
a: 1,
[Symbol('d')]: 2, // 不可迭代Symbol属性
c: 3,
d: 4
};
Object.defineProperty(obj, 'c', {
enumerable: false // 不可迭代不可枚举属性
});
for (let key in obj) {
console.log(key, obj[key]);
}
// 输出: a 1, d 4
3、可以枚举继承的可枚举属性
let obj = {
a: 1,
b: 2
};
Object.prototype.c = 3; // 继承的可枚举属性
Object.defineProperty(obj, 'a', {
enumerable: false
});
for (let key in obj) {
console.log(key, obj[key]);
}
// 输出: b,2 c 3
4、迭代注重的是属性
for (let key in obj) {}
for (let index in arr) {}
// 开头已经说了for...in是遍历对象属性而构建的,所以获取值需要obj[key]/arr[index]
for…of
for…of语句在
可迭代对象
上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句 。
可迭代对象:对象或者原型链上必须有一个键为[Symbol.iterator]
的属性。可迭代对象包括:
- Map
- Set
- Array
- TypeArray(类数组)
- String
使用:
// 迭代map
const map = new Map([
[{ a: 1}, 'a'],
[{ b: 2}, 'b'],
[{ c: 3}, 'c'],
]);
for (let [key, value] of map) {
console.log(key, value); // 输出: { a: 1 } a, { b: 2 } b, { c: 3 } c
}
// 迭代set
const set = new Set([1, 2, 3, 4]);
for (let value of set) {
console.log(value); // 输出: 1,2,3,4
}
// 迭代Array
const arr = [1, 2, 3, 4];
for (let value of arr) {
console.log(value); // 输出: 1,2,3,4
}
// 迭代类数组
function typeArray() {
for (let value of arguments) {
console.log(value); // 输出: 1,2,3,4
}
}
typeArray(1,2,3,4);
// 迭代string
const str = '1234';
for (let value of str) {
console.log(value); // 输出: 1,2,3,4
}
可以看到for…of迭代出来的都是值,说明for…of注重的是值。
总结
- 使用场景上:for…in用来迭代对象,for…of用来迭代数组。对象没有
Symbol.iterator
属性所以无法使用for…of,但是数组因为也是对象,所以可以使用for…in - 迭代过程上:for…in会迭代自身原型链上的可迭代属性和方法,for…of不会
- 迭代结果上:for…in获取到的是键,for…of获取到的是值