三葉Leaves Author

经常被 for...infor...of 搞晕,记不住他俩的区别。学 Vue 的时候遇到 v-for ,里面用的是 in ,这使我更加迷惑。干脆稍微整理了一下,方便以后速记。

总结先行

  • for..in.. 遍历的是索引,现代开发拿来遍历普通对象(也能用于数组,但不推荐)
  • for...of... 遍历的是值,拿来遍历数组或者字符串等,但不能用于对象(想想看遍历对象的值是什么鬼?顺序也难以预测)
  • v-for 是 vue 中强大的工具,啥都能遍历,但是最好也指定一下 :key
特性 for...in (JavaScript) for...of (JavaScript) v-for (Vue 模板)
遍历目标 对象的可枚举属性名 (key) 可迭代对象 (Iterable) 的值 (value) 数组的元素或者对象的
遍历数组得到 索引 (字符串类型) "0", "1", "2" 元素值 1, 2, 3 元素值 (默认) item
遍历对象得到 属性名 (key) "name", "age" 直接用会报错 (普通对象默认不可迭代) 属性值 (默认) value
会遍历原型链吗 不会 不会
推荐使用场景 遍历普通对象 (但要注意原型链问题) 遍历数组、Set、Map、字符串等 在 Vue 模板中渲染列表
语法关键词 in of in (但行为更像 for...of)

1. for...in (为遍历对象属性而生)

for...in 语句用于循环遍历对象的可枚举属性(enumerable properties),它遍历的是键名 (key)

主要特点:

  1. 遍历键名 (Key):它返回的是对象的键名(或数组的索引)。
  2. 键名为字符串:即使是数组的索引,返回的也是字符串类型,如 "0", "1", "2"
  3. 会遍历原型链:它会遍历对象自身及其原型链上所有可枚举的属性。这是它最大的一个“坑”,通常需要配合 hasOwnProperty() 方法来只获取对象自身的属性。
  4. 顺序不保证:在某些旧的 JavaScript 引擎中,遍历顺序是不确定的。

示例:

遍历对象:

1
2
3
4
5
6
7
8
9
const user = {
name: 'Alice',
age: 30
};

for (const key in user) {
console.log(key); // 输出: "name", "age"
console.log(user[key]); // 输出: "Alice", 30
}

遍历数组 (不推荐):

1
2
3
4
5
6
const arr = ['a', 'b', 'c'];

for (const index in arr) {
console.log(index); // 输出: "0", "1", "2" (字符串类型)
console.log(arr[index]); // 输出: "a", "b", "c"
}

为什么不推荐用 for...in 遍历数组?因为如果有人修改了 Array.prototypefor...in 会把它也遍历出来。

1
2
3
4
5
6
Array.prototype.customMethod = function() {};
const arr = ['a', 'b', 'c'];

for (const index in arr) {
console.log(index); // 输出: "0", "1", "2", "customMethod"
}

2. for...of (为遍历可迭代对象的值而生)

for...of 是 ES6 新增的语法,它专门用于遍历可迭代对象 (Iterable)值 (value)

常见的可迭代对象包括:Array, String, Map, Set, arguments 对象, NodeList 等。

主要特点:

  1. 遍历值 (Value):直接获取集合中的值,而不是键或索引。
  2. 不会遍历原型链:非常干净,只关心数据本身。
  3. 普通对象不可用:默认的普通对象 {} 不是可迭代对象,直接使用 for...of 会抛出 TypeError
  4. 可以中断:和 for 循环一样,可以使用 break, continue, return

示例:

遍历数组 (推荐):

1
2
3
4
5
const arr = ['a', 'b', 'c'];

for (const value of arr) {
console.log(value); // 输出: "a", "b", "c"
}

遍历字符串:

1
2
3
4
5
const str = "hello";

for (const char of str) {
console.log(char); // 输出: "h", "e", "l", "l", "o"
}

遍历普通对象 (会报错):

1
2
3
4
5
6
const user = { name: 'Alice', age: 30 };

for (const value of user) {
// Uncaught TypeError: user is not iterable
console.log(value);
}

3. v-for 在 Vue 中的使用

现在来看关键问题:v-for 到底像谁?

结论:v-for 的语法虽然使用 in 关键字,但其行为设计上更接近 JavaScript 的 for...of,并且对其功能进行了增强,使其也能方便地遍历对象。

你不能在 v-for 中使用 of 关键字,语法是固定的,必须用 in

v-for 的行为分析:

  1. 遍历数组
    它的行为和 for...of 非常相似,都是遍历数组的元素值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <ul>
    <!-- item 就是数组中的每个元素值 -->
    <li v-for="item in items">{{ item.message }}</li>
    </ul>

    <!-- 还可以同时获取索引,这是 v-for 的增强功能 -->
    <ul>
    <li v-for="(item, index) in items">
    {{ index }} - {{ item.message }}
    </li>
    </ul>

    这里的 item in items 行为上等同于 for (const item of items)

  2. 遍历对象
    这是 v-for 和原生 JS 循环区别最大的地方。v-for 为遍历对象提供了非常便利的方式。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    <ul>
    <!-- 默认遍历的是对象的 value -->
    <li v-for="value in myObject">
    {{ value }}
    </li>
    </ul>

    <!-- 可以同时获取 key -->
    <ul>
    <li v-for="(value, key) in myObject">
    {{ key }}: {{ value }}
    </li>
    </ul>

    <!-- 甚至可以同时获取 key 和 index -->
    <ul>
    <li v-for="(value, key, index) in myObject">
    {{ index }}. {{ key }}: {{ value }}
    </li>
    </ul>
    • 默认的 value in myObject 遍历的是,这和 for...in(遍历键)以及 for...of(会报错)都不同。
    • 它提供了获取 (value, key, index) 的元组语法,这是 Vue 特有的便利功能。

总结与辨析

  • for...in 是一个有点“过时”且存在陷阱(原型链)的循环,主要用于检查对象的
  • for...of 是现代 JavaScript 中遍历的首选方式,适用于所有可迭代对象,尤其是数组。
  • v-for 是 Vue 模板中的指令,它借用了 in 这个关键字,但其设计哲学是为了方便地在视图中渲染列表。它对数组的遍历方式类似 for...of,并对对象的遍历进行了独有的、强大的功能扩展。

所以,请务必将 JavaScript 中的 for...inVue 中的 v-for="... in ..." 当作两种完全不同的东西来理解,尽管它们碰巧都用了 in 关键字。

  • 标题:
  • 作者: 三葉Leaves
  • 创建于 : 2025-06-22 00:00:00
  • 更新于 : 2025-07-10 13:40:50
  • 链接: https://blog.oksanye.com/3931368c90a5/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论