for in 和 for of的区别详解

本文详细对比了forin与forof循环在遍历对象与数组时的不同表现,阐述了两者各自的特点及其适用场景,并解释了forof如何实现对各种数据结构的遍历。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

for in 和 for of 相对于大家肯定都不陌生,都是用来遍历属性的没错。那么先看下面的一个例子:

例1

const obj = {
  a: 1,
  b: 2,
  c: 3
}
for (let i in obj) {
  console.log(i)
  // a
  // b
  // c
}
for (let i of obj) {
  console.log(i)
  // Uncaught TypeError: obj is not iterable 报错了
}

以上代码通过 for in 和 for of 对一个obj对象进行遍历,for in 正常的获取了对象的 key值,分别打印 a、b、c,而 for of却报错了。

例2:
以上是遍历对象,下面再看一个遍历数组的例子。

const arr = ['a', 'b', 'c']
// for in 循环
for (let i in arr) {
    console.log(i)
    // 0
    // 1
    // 2
}

// for of
for (let i of arr) {
    console.log(i)
    // a
    // b
    // c
}

以上代码是对一个数组进行遍历, for in 返回的值为 0、1、2,这不是数组的下标吗? 而 for of 返回的是 a、b、c,这一次没有报错,为什么呢?

例3
const arr = [‘a’, ‘b’]
// 手动给 arr数组添加一个属性
arr.name = ‘qiqingfu’

// for in 循环可以遍历出 name 这个键名
for (let i in arr) {
    console.log(i)
    // a
    // b
    // name
}

for in 的特点

结合上面的两个例子,分析得出:

for … in 循环返回的值都是数据结构的 键值名。
遍历对象返回的对象的key值,遍历数组返回的数组的下标(key)。

for … in 循环不仅可以遍历数字键名,还会遍历原型上的值和手动添加的其他键。如——例3

特别情况下, for … in 循环会以任意的顺序遍历键名

总结一句: for in 循环特别适合遍历对象。

for of 特点

for of 循环用来获取一对键值对中的值,而 for in 获取的是 键名

一个数据结构只要部署了 Symbol.iterator 属性, 就被视为具有 iterator接口, 就可以使用 for of循环。

例1这个对象,没有 Symbol.iterator这个属性,所以使用 for of会报 obj is not iterable

for of 不同与 forEach, 它可以与 break、continue和return 配合使用,也就是说 for of 循环可以随时退出循环。

提供了遍历所有数据结构的统一接口

哪些数据结构部署了 Symbol.iteratoer属性了呢?

只要有 iterator 接口的数据结构,都可以使用 for of循环。

数组 Array

Map

Set

String

arguments对象

Nodelist对象, 就是获取的dom列表集合

以上这些都可以直接使用 for of 循环。 凡是部署了 iterator 接口的数据结构也都可以使用数组的 扩展运算符(…)、和解构赋值等操作。

我也想让对象可以使用 for of循环怎么办?使用 Object.keys() 获取对象的 key值集合后,再使用 for of

以例1为例

const obj = {
    a: 1,
    b: 2,
    c: 3
}

for (let i of Object.keys(obj)) {
    console.log(i)
    // 1
    // 2
    // 3
}

也可以给一个对象部署 Symbol.iterator属性。

<think>我们正在讨论Vue.jsfor...infor...of循环的区别。注意,在Vue模板中,我们通常使用v-for指令进行循环,而v-for内部使用的是for...of(针对数组)或for...in(针对对象)的语义。但这里我们主要讨论在Vue的JavaScript部分(如methods、computed等)使用这两种循环的区别,以及它们与v-for指令的关系。 根据用户的问题,我们需要解释for...infor...of在JavaScript中的区别,并特别指出在Vue.js环境下的使用注意事项。 引用[3]中提到:“在Vue开发中,for循环是我们最常遇见的场景之一,我们知道常见的遍历方式有for循环,for offorEach、for in.虽然在开发过程中,这几种方式基本上可以满足我们大多数的场景,但是你真的知道他们之间的区别吗?接下来跟大家分享一下他们之间的差异 始终在v-for循环中使用key”。 因此,我们将首先解释两种循环的基本区别,然后说明在Vue中(特别是v-for指令)的使用。 ### 区别详解 1. **for...in循环**: - 用于遍历对象的可枚举属性(包括原型链上的属性)。 - 遍历的是键(key),对于数组,遍历的是索引(字符串类型)。 - 不保证顺序(虽然数组的索引是有序的,但对象属性顺序可能因引擎而异)。 - 通常用于遍历对象,而不是数组。 2. **for...of循环**: - 用于遍历可迭代对象(如数组、Map、Set、String等)。 - 遍历的是值(value)。 - 保证顺序(按照可迭代对象的顺序)。 - 不能直接遍历普通对象(因为普通对象不是可迭代对象),除非使用Object.keys()等方法。 ### 在Vue.js中的使用 - **在模板中使用v-for**: - 当遍历数组时,v-for内部类似于for...of,因为它遍历数组元素。语法为:`v-for="(item, index) in array"`。 - 当遍历对象时,v-for内部类似于for...in,因为它遍历对象的属性。语法为:`v-for="(value, key) in object"`。 - 注意:在v-for中,我们总是需要为每个节点指定一个唯一的key(引用[3][4]都强调了这一点)。 - **在Vue的JavaScript部分(如方法、计算属性)**: - 你可以自由选择使用for...infor...of,但需要根据遍历的目标类型选择: - 遍历数组:推荐使用for...of(或forEach、普通for循环)。 - 遍历对象:推荐使用for...in(但通常配合`Object.hasOwnProperty`检查,以避免遍历到原型链上的属性),或者使用`Object.keys`、`Object.values`、`Object.entries`等方法。 ### 示例 假设我们有一个Vue实例,其中包含一个数组一个对象: ```javascript data() { return { fruits: ['apple', 'banana', 'orange'], person: { name: 'John', age: 30, job: 'developer' } }; } ``` - 使用for...of遍历数组(在方法中): ```javascript methods: { printFruits() { for (const fruit of this.fruits) { console.log(fruit); } } } ``` - 使用for...in遍历对象(在方法中): ```javascript methods: { printPerson() { for (const key in this.person) { // 确保key是对象自身的属性,而不是继承的 if (this.person.hasOwnProperty(key)) { console.log(key, this.person[key]); } } } } ``` ### 注意事项 - 在Vue的响应式系统中,使用循环修改数组或对象时,需要注意Vue的响应式更新规则。例如,直接通过索引修改数组元素(如`this.fruits[0] = 'pear'`)不会触发视图更新,应使用Vue.set或数组的splice方法。 - 在v-for指令中,不推荐同时使用v-if,因为v-for的优先级比v-if高(在Vue 2中),这可能导致不必要的性能问题。如果必须条件渲染,可以在循环前对数组进行过滤。 ### 总结 在Vue.js中: - for...in循环主要用于遍历对象的属性。 - for...of循环主要用于遍历数组或其他可迭代对象。 - 在v-for指令中,Vue根据遍历的是数组还是对象自动选择类似for...offor...in的语义。 - 在JavaScript代码部分,根据遍历目标选择循环方式,并注意Vue的响应式规则。 §§相关问题§§ 1. 在Vue.js中,如何正确遍历数组并更新视图? 2. Vue的v-for指令中为什么必须使用key属性? 3. 在Vue中,如何遍历一个对象的所有属性? 4. 如何避免for...in循环遍历到对象的原型链属性?</think>### Vue.js 中 `for...in` 与 `for...of` 循环的区别 在 Vue.js 开发中,`for...in` `for...of` 是两种常见的循环方式,但它们的用途行为有本质区别: #### 1. **`for...in` 循环** - **用途**:遍历对象的**可枚举属性**(包括原型链上的属性)。 - **返回值**:对象的**键名(key)**。 - **适用对象**:普通对象(`Object`)、数组(但会遍历索引)。 - **Vue 中的注意事项**: - 在遍历数组时,会返回**数字索引(字符串形式)**,而非元素值。 - 可能遍历到原型链上的非自有属性,需配合 `hasOwnProperty` 过滤。 ```javascript // 示例:遍历对象 const obj = { name: 'Vue', version: 3 }; for (const key in obj) { console.log(key); // 输出: "name", "version" } ``` #### 2. **`for...of` 循环** - **用途**:遍历**可迭代对象**的值(如数组、Map、Set)。 - **返回值**:对象的**值(value)**。 - **适用对象**:数组、字符串、Map、Set 等实现了 `[Symbol.iterator]` 接口的对象。 - **Vue 中的优势**: - 直接获取元素值,无需通过索引访问。 - 不遍历原型链属性,避免意外行为。 ```javascript // 示例:遍历数组 const arr = ['Vue', 'React', 'Angular']; for (const item of arr) { console.log(item); // 输出: "Vue", "React", "Angular" } ``` --- ### 核心区别总结 | **特性** | `for...in` | `for...of` | |------------------|----------------------------|----------------------------| | **遍历目标** | 对象的键名(key) | 可迭代对象的值(value) | | **适用场景** | 普通对象 | 数组、Map、Set 等 | | **原型链属性** | 会遍历 | 不会遍历 | | **数组处理** | 返回索引(字符串) | 直接返回值 | | **可迭代性要求** | 不需要 | 需要对象实现迭代器接口 | --- ### 在 Vue 中的实际应用 1. **`v-for` 指令的底层行为** Vue 的 `v-for` 在遍历数组时**类似 `for...of`**(直接获取值),遍历对象时**类似 `for...in`**(获取键值对)[^3][^4]: ```html <!-- 遍历数组 --> <div v-for="(item, index) in arr" :key="index"> {{ item }} <!-- 直接访问元素值 --> </div> <!-- 遍历对象 --> <div v-for="(value, key) in obj" :key="key"> {{ key }}: {{ value }} </div> ``` 2. **性能与安全性** - 遍历数组时**优先使用 `for...of`**,避免 `for...in` 返回索引导致的额外操作。 - 遍历对象时使用 `for...in`,但需配合 `Object.hasOwnProperty` 过滤原型链属性: ```javascript for (const key in obj) { if (Object.hasOwnProperty.call(obj, key)) { // 安全操作自有属性 } } ``` 3. **响应式数据注意事项** Vue 的响应式系统对数组对象的处理不同: - 修改数组时,需使用 `Vue.set` 或数组的变更方法(如 `push`、`splice`)触发更新。 - 修改对象时,直接添加新属性需用 `Vue.set` 确保响应式[^2]。 --- ### 何时选择? - **用 `for...of`**: 需要遍历数组、Map、Set 的值时(如渲染列表)。 - **用 `for...in`**: 需要遍历对象的键名时(如动态处理对象属性)。 > 提示:在 Vue 模板中始终为 `v-for` 添加 `:key`,以提高性能并避免渲染错误[^3][^4]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值