ES6规定for...in和for...of有什么区别

164 阅读3分钟

ES6规定for...in和for...of有什么区别

ES6 中的 for...infor...of 是两种不同的循环语法,它们的主要区别在于遍历的对象遍历的内容。以下是它们的详细区别:

  1. 遍历的对象
  • for...in
    • 用于遍历对象的可枚举属性(包括原型链上的属性)。
    • 适用于普通对象(Object)。
  • for...of
    • 用于遍历可迭代对象(实现了 [Symbol.iterator] 方法的对象)。
    • 适用于数组、字符串、Map、Set 等可迭代对象。
  1. 遍历的内容
  • for...in
    • 遍历的是对象的键名(key)
    • 对于数组,遍历的是数组的索引(字符串形式的数字)。
  • for...of
    • 遍历的是对象的值(value)
    • 对于数组,遍历的是数组的元素
  1. 示例对比

#遍历数组

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);
}
  1. 原型链上的属性
  • 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:不能遍历普通对象
  1. 适用场景
  • for...in
    • 适合遍历对象的键名。
    • 需要过滤原型链属性时,结合 hasOwnProperty 使用。
  • for...of
    • 适合遍历数组、字符串、Map、Set 等可迭代对象的值。
    • 不能直接遍历普通对象,除非对象实现了 [Symbol.iterator] 方法。
  1. 遍历 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
}
  1. 遍历字符串

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
}
  1. 性能
  • for...in
    • 由于会遍历原型链上的属性,性能可能稍差。
  • for...of
    • 直接遍历值,性能较好。
  1. 总结对比
特性for...infor...of
遍历对象普通对象可迭代对象(数组、字符串、Map、Set 等)
遍历内容键名(key)值(value)
原型链属性会遍历原型链上的属性不会遍历原型链
适用场景遍历对象的键名遍历可迭代对象的值
直接遍历普通对象支持不支持(除非实现[Symbol.iterator]
直接遍历数组遍历索引遍历元素
直接遍历字符串遍历索引遍历字符
直接遍历 Map/Set不支持支持
  1. 如何选择
  • 如果需要遍历对象的键名,使用 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...infor...of 是两种不同的遍历语法,分别适用于不同的场景。for...in 用于遍历对象的键名,而 for...of 用于遍历可迭代对象的值。根据实际需求选择合适的遍历方式,可以使代码更加清晰和高效。

更多vue相关插件及后台管理模板可访问vue admin reference,代码详情请访问github