JavaScript 和 Vue3 中 for...in 与 for...of 的区别

我来详细解释一下 JavaScript 和 Vue3 中 for...infor...of 的区别。

参考 列表渲染 | Vue.js

在 JavaScript 中的区别

for...in

  • 用途 :遍历对象的可枚举属性名(键名)
  • 遍历内容:属性名/索引
  • 适用对象:对象、数组、字符串等
javascript 复制代码
// 遍历对象
const obj = { name: 'Alice', age: 25, city: 'Beijing' };
for (let key in obj) {
    console.log(key); // name, age, city
    console.log(obj[key]); // Alice, 25, Beijing
}

// 遍历数组
const arr = ['a', 'b', 'c'];
for (let index in arr) {
    console.log(index); // 0, 1, 2 (注意:是字符串)
    console.log(arr[index]); // a, b, c
}

for...of

  • 用途 :遍历可迭代对象的值
  • 遍历内容:属性值
  • 适用对象:数组、字符串、Map、Set、NodeList 等
javascript 复制代码
// 遍历数组
const arr = ['a', 'b', 'c'];
for (let value of arr) {
    console.log(value); // a, b, c
}

// 遍历字符串
const str = 'hello';
for (let char of str) {
    console.log(char); // h, e, l, l, o
}

// 遍历 Map
const map = new Map([['name', 'Alice'], ['age', 25]]);
for (let [key, value] of map) {
    console.log(key, value); // name Alice, age 25
}

在 Vue3 中的使用

在模板中使用 v-for

vue 复制代码
<template>
  <!-- 使用 for...of 的思想:遍历值 -->
  <ul>
    <li v-for="item in items" :key="item.id">
      {{ item.name }}
    </li>
  </ul>
  
  <!-- 遍历对象属性:类似 for...in -->
  <div v-for="(value, key) in user" :key="key">
    {{ key }}: {{ value }}
  </div>
  
  <!-- 获取索引:类似 for...in 的索引 -->
  <div v-for="(item, index) in items" :key="item.id">
    {{ index }}: {{ item.name }}
  </div>
</template>

<script setup>
import { ref } from 'vue'

const items = ref([
  { id: 1, name: 'Apple' },
  { id: 2, name: 'Banana' },
  { id: 3, name: 'Orange' }
])

const user = ref({
  name: 'Alice',
  age: 25,
  city: 'Beijing'
})
</script>

在 Composition API 中使用

vue 复制代码
<script setup>
import { ref, onMounted } from 'vue'

const users = ref([
  { id: 1, name: 'Alice', age: 25 },
  { id: 2, name: 'Bob', age: 30 },
  { id: 3, name: 'Charlie', age: 35 }
])

const userInfo = ref({
  name: 'Alice',
  age: 25,
  email: 'alice@example.com'
})

onMounted(() => {
  // 使用 for...of 遍历数组值
  for (const user of users.value) {
    console.log(user.name, user.age)
  }
  
  // 使用 for...in 遍历对象属性
  for (const key in userInfo.value) {
    console.log(key, userInfo.value[key])
  }
  
  // 注意:Vue3 的响应式对象可能包含额外属性
  for (const key in userInfo.value) {
    // 过滤掉 Vue 内部属性
    if (userInfo.value.hasOwnProperty(key)) {
      console.log(key, userInfo.value[key])
    }
  }
})
</script>

实际应用对比

javascript 复制代码
// 原始数据
const products = [
  { id: 1, name: 'iPhone', price: 999 },
  { id: 2, name: 'iPad', price: 599 }
]

const productMap = {
  '1': { name: 'iPhone', price: 999 },
  '2': { name: 'iPad', price: 599 }
}

// JavaScript 中的遍历
console.log('=== for...in ===')
for (let index in products) {
    console.log('Index:', index, 'Type:', typeof index) // 字符串类型
    console.log('Value:', products[index])
}

for (let key in productMap) {
    console.log('Key:', key)
    console.log('Value:', productMap[key])
}

console.log('=== for...of ===')
for (let product of products) {
    console.log('Product:', product)
}

// Vue3 模板中的对应写法
vue 复制代码
<template>
  <!-- 对应 for...in 遍历数组索引 -->
  <div v-for="(product, index) in products" :key="index">
    Index: {{ index }} <!-- 这里的 index 类似 for...in 的 key -->
    Product: {{ product.name }}
  </div>
  
  <!-- 对应 for...in 遍历对象 -->
  <div v-for="(value, key) in productMap" :key="key">
    Key: {{ key }} <!-- 对应 for...in 的属性名 -->
    Value: {{ value }} <!-- 对应 for...in 的属性值 -->
  </div>
  
  <!-- 对应 for...of 遍历值 -->
  <div v-for="product in products" :key="product.id">
    {{ product.name }} - ${{ product.price }} <!-- 直接使用值 -->
  </div>
</template>

关键区别总结

特性 for...in for...of
遍历内容 属性名/索引 属性值
数据类型 对象、数组等 可迭代对象
索引类型 字符串 数字
Vue模板 (value, key) value
适用场景 遍历对象属性 遍历数组元素

在 Vue3 中,v-for 的语法设计很好地融合了两种遍历方式的特点,让开发者可以根据需要选择合适的写法。

相关推荐
前端工作日常8 分钟前
H5 实时摄像头 + 麦克风:完整可运行 Demo 与深度拆解
前端·javascript
韩沛晓19 分钟前
uniapp跨域怎么解决
前端·javascript·uni-app
前端工作日常20 分钟前
以 Vue 项目为例串联eslint整个流程
前端·eslint
程序员鱼皮21 分钟前
太香了!我连夜给项目加上了这套 Java 监控系统
java·前端·程序员
该用户已不存在1 小时前
这几款Rust工具,开发体验直线上升
前端·后端·rust
前端雾辰1 小时前
Uniapp APP 端实现 TCP Socket 通信(ZPL 打印实战)
前端
无羡仙1 小时前
虚拟列表:怎么显示大量数据不卡
前端·react.js
云水边1 小时前
前端网络性能优化
前端
用户51681661458411 小时前
[微前端 qiankun] 加载报错:Target container with #child-container not existed while devi
前端
武昌库里写JAVA1 小时前
使用 Java 开发 Android 应用:Kotlin 与 Java 的混合编程
java·vue.js·spring boot·sql·学习