ES6规定for...in和for...of有什么区别
ES6 中的 for...in 和 for...of 是两种不同的循环语法,它们的主要区别在于遍历的对象和遍历的内容。以下是它们的详细区别:
- 遍历的对象
for...in:- 用于遍历对象的可枚举属性(包括原型链上的属性)。
- 适用于普通对象(
Object)。
for...of:- 用于遍历可迭代对象(实现了
[Symbol.iterator]方法的对象)。 - 适用于数组、字符串、Map、Set 等可迭代对象。
- 用于遍历可迭代对象(实现了
- 遍历的内容
for...in:- 遍历的是对象的键名(key)。
- 对于数组,遍历的是数组的索引(字符串形式的数字)。
for...of:- 遍历的是对象的值(value)。
- 对于数组,遍历的是数组的元素。
- 示例对比
#遍历数组
const array = [10, 20, 30];
// for...in:遍历索引
for (let index in array) {
console.log(index); // 0, 1, 2
}
// for...of:遍历元素
for (let value of array) {
console.log(value); // 10, 20, 30
}
#遍历对象
const obj = { a: 1, b: 2, c: 3 };
// for...in:遍历键名
for (let key in obj) {
console.log(key); // a, b, c
}
// for...of:不能直接遍历普通对象
// 以下代码会报错:TypeError: obj is not iterable
for (let value of obj) {
console.log(value);
}
- 原型链上的属性
for...in:- 会遍历对象自身及其原型链上的可枚举属性。
- 可以使用
hasOwnProperty过滤掉原型链上的属性。
for...of:- 只遍历对象自身的值,不会遍历原型链。
示例:
const parent = { a: 1 };
const child = Object.create(parent);
child.b = 2;
// for...in:遍历自身和原型链上的属性
for (let key in child) {
console.log(key); // b, a
}
// 使用 hasOwnProperty 过滤
for (let key in child) {
if (child.hasOwnProperty(key)) {
console.log(key); // b
}
}
// for...of:不能遍历普通对象
- 适用场景
for...in:- 适合遍历对象的键名。
- 需要过滤原型链属性时,结合
hasOwnProperty使用。
for...of:- 适合遍历数组、字符串、Map、Set 等可迭代对象的值。
- 不能直接遍历普通对象,除非对象实现了
[Symbol.iterator]方法。
- 遍历 Map 和 Set
for...of 可以直接遍历 Map 和 Set,而 for...in 不能。
示例:
const map = new Map([
['a', 1],
['b', 2]
]);
// for...of:遍历 Map 的键值对
for (let [key, value] of map) {
console.log(key, value); // a 1, b 2
}
const set = new Set([1, 2, 3]);
// for...of:遍历 Set 的值
for (let value of set) {
console.log(value); // 1, 2, 3
}
- 遍历字符串
for...of 可以正确遍历字符串的字符,而 for...in 遍历的是字符串的索引。
示例:
const str = 'hello';
// for...in:遍历索引
for (let index in str) {
console.log(index); // 0, 1, 2, 3, 4
}
// for...of:遍历字符
for (let char of str) {
console.log(char); // h, e, l, l, o
}
- 性能
for...in:- 由于会遍历原型链上的属性,性能可能稍差。
for...of:- 直接遍历值,性能较好。
- 总结对比
| 特性 | for...in | for...of |
|---|---|---|
| 遍历对象 | 普通对象 | 可迭代对象(数组、字符串、Map、Set 等) |
| 遍历内容 | 键名(key) | 值(value) |
| 原型链属性 | 会遍历原型链上的属性 | 不会遍历原型链 |
| 适用场景 | 遍历对象的键名 | 遍历可迭代对象的值 |
| 直接遍历普通对象 | 支持 | 不支持(除非实现[Symbol.iterator]) |
| 直接遍历数组 | 遍历索引 | 遍历元素 |
| 直接遍历字符串 | 遍历索引 | 遍历字符 |
| 直接遍历 Map/Set | 不支持 | 支持 |
- 如何选择
- 如果需要遍历对象的键名,使用
for...in。 - 如果需要遍历数组、字符串、Map、Set 等的值,使用
for...of。 - 如果需要遍历普通对象的值,可以先将对象转换为数组(如
Object.values(obj)),然后使用for...of。
示例:遍历对象的值
const obj = { a: 1, b: 2, c: 3 };
// 使用 Object.values 将对象的值转换为数组
for (let value of Object.values(obj)) {
console.log(value); // 1, 2, 3
}
总结
for...in 和 for...of 是两种不同的遍历语法,分别适用于不同的场景。for...in 用于遍历对象的键名,而 for...of 用于遍历可迭代对象的值。根据实际需求选择合适的遍历方式,可以使代码更加清晰和高效。
更多vue相关插件及后台管理模板可访问vue admin reference,代码详情请访问github