当前位置: 首页 > news >正文

【JS】for-in 和 for-of遍历对象的区别

【介绍】

for-infor-of 都是 JavaScript 中用于遍历数据结构的循环语句,但它们的工作原理和适用场景有所不同。特别是它们在遍历对象时的行为是不同的。

【区别】

for-in 遍历对象

  • for-in 是用于遍历对象的 可枚举属性的键名(属性名),它会遍历对象自身以及继承的属性(从原型链继承的属性)。这种遍历顺序并不是固定的,因此在遍历时,键名的顺序不一定是按添加顺序排列的。
示例:
const obj = { a: 1, b: 2, c: 3 };for (let key in obj) {console.log(key);  // 输出属性名: "a", "b", "c"console.log(obj[key]);  // 输出属性值: 1, 2, 3
}
  • for-in 遍历的是 属性名(键),可以通过 obj[key] 获取对应的值。
  • 它也会遍历继承自原型链的属性。
注意:
  • for-in 可能遍历到对象的原型链上的属性,因此通常在遍历对象时要使用 hasOwnProperty 来过滤掉继承的属性:
for (let key in obj) {if (obj.hasOwnProperty(key)) {console.log(key, obj[key]);  // 只输出 obj 自有属性}
}

for-of 遍历对象

  • for-of 主要用于遍历 可迭代对象(如数组、字符串、Map、Set 等),它可以直接遍历这些对象的 元素值普通对象(如 {})不是可迭代对象,因此不能使用 for-of 遍历对象
示例:
const arr = [1, 2, 3, 4];for (let value of arr) {console.log(value);  // 输出:1, 2, 3, 4
}
  • for-of 遍历的是 数组元素的值,并不像 for-in 那样遍历键名。

区别总结:

特性for-infor-of
遍历目标对象的 属性名(键名)可迭代对象的
适用场景用于遍历对象的属性用于遍历数组、字符串、Set、Map 等可迭代对象的值
遍历顺序遍历对象属性的顺序不固定遍历顺序是固定的,按数组的顺序遍历元素
遍历对象时的行为遍历对象的所有可枚举属性,包括原型链上的属性不适用于对象,适用于数组等可迭代对象
是否遍历原型链会遍历继承的属性不会遍历原型链上的元素
对象如何使用 for-of 遍历?

由于普通对象是不可迭代的,不能直接使用 for-of 来遍历对象。如果你希望遍历对象的值或键,可以先使用 Object.keys(), Object.values()Object.entries() 来将对象转化为可迭代的结构,然后使用 for-of 遍历。

示例:使用 for-of 遍历对象的键和值
const obj = { a: 1, b: 2, c: 3 };// 遍历键
for (let key of Object.keys(obj)) {console.log(key);  // 输出:a, b, c
}// 遍历值
for (let value of Object.values(obj)) {console.log(value);  // 输出:1, 2, 3
}// 遍历键值对
for (let [key, value] of Object.entries(obj)) {console.log(key, value);  // 输出:a 1, b 2, c 3
}

【总结】

  • for-in 用于遍历 对象的属性名,适合遍历对象本身及其原型链上的属性。
  • for-of 用于遍历 可迭代对象的元素值,常用于遍历数组、字符串、Set 和 Map 等类型。对于普通对象,通常先将对象转化为可迭代的结构后才能使用 for-of

补充

for-in遍历对象时属性顺序不固定

在 JavaScript 中,for-in 遍历对象时的属性顺序确实不是固定的。特别是对于对象的 数字类型的键名,浏览器的行为可能会不同,但根据 ECMAScript 规范,对于普通对象来说, 字符串类型的键名会按添加顺序遍历,而数字键名会按数值顺序遍历

然而,这个顺序并不是严格保证的,尤其是在老版本的浏览器中,可能会出现不同的行为。为了演示这种不固定顺序的行为,我们可以考虑以下代码示例,展示不同类型的键名如何影响 for-in 的遍历顺序。

示例:for-in 遍历顺序
const obj = {'3': 'three',   // 数字类型的键'1': 'one',     // 数字类型的键'2': 'two',     // 数字类型的键'a': 'apple',   // 字符串类型的键'b': 'banana',  // 字符串类型的键'z': 'zebra'    // 字符串类型的键
};for (let key in obj) {console.log(key);  // 输出属性名(键)
}
输出:
1
2
3
a
b
z
解释:
  1. 数字键'1', '2', '3')按数值顺序排列,先输出数字键。
  2. 字符串键'a', 'b', 'z')按添加顺序排列,紧随其后。
示例:for-in 的原型链行为

for-in 不仅会遍历对象本身的属性,还会遍历继承的属性(即原型链上的属性)。因此,如果对象有继承的属性或方法,for-in 会遍历这些继承的属性。

const obj = {name: 'Alice',age: 25
};Object.prototype.sayHello = function() {console.log('Hello!');
};for (let key in obj) {console.log(key);  // 输出:name, age, sayHello
}
输出:
name
age
sayHello
解释:

for-in 会遍历 obj 的自有属性和继承的属性,因此 sayHello 也被遍历到。

小结:
  • for-in 的遍历顺序并不完全固定,尤其是数字类型的键名的顺序可能因不同的 JavaScript 引擎而有所不同。
  • 对于字符串类型的键,for-in 通常会按照对象中添加的顺序遍历。
  • for-in 还会遍历继承自原型链上的属性,因此需要特别注意过滤掉继承的属性。
http://www.lryc.cn/news/512587.html

相关文章:

  • 【每日学点鸿蒙知识】ets匿名类、获取控件坐标、Web显示iframe标签、软键盘导致上移、改变Text的背景色
  • 深度学习blog- 数学基础(全是数学)
  • 最后100米配送
  • Linux的进程替换以及基础IO
  • 《计算机网络A》单选题-复习题库
  • 闲谭Scala(2)--安装与环境配置
  • Python基于卷积神经网络的车牌识别系统开发与实现
  • Spring Boot集成Netty创建一个TCP服务器,接收16进制数据(自定义解码器和编码器)
  • Python 中的 with open:文件操作的最佳实践
  • 哪些框架、软件、中间件使用了netty? 哪些中间件、软件底层使用了epoll?
  • AI 智能助手对话系统
  • 2024年秋词法分析作业(满分25分)
  • Docker镜像瘦身:从1.43G到22.4MB
  • 前端加解密对抗encrypt-labs
  • Android Notification 问题:Invalid notification (no valid small icon)
  • Python爬虫教程——7个爬虫小案例(附源码)_爬虫实例
  • Log4j2的Policies详解、SizeBasedTriggeringPolicy、TimeBasedTriggeringPolicy
  • ES中查询中参数的解析
  • 学习笔记:使用 pandas 和 Seaborn 绘制柱状图
  • 【每日学点鸿蒙知识】placement设置top、组件携带自定义参数、主动隐藏输入框、Web设置字体、对话框设置全屏宽
  • 后端开发-Maven
  • 自动化办公-合并多个excel
  • mavlink移植到单片机stm32f103c8t6,实现接收和发送数据
  • 小程序基础 —— 08 文件和目录结构
  • FIR数字滤波器设计——窗函数设计法——滤波器的时域截断
  • MySQLOCP考试过了,题库很稳,经验分享。
  • WPF 绘制过顶点的圆滑曲线 (样条,贝塞尔)
  • Kafka 幂等性与事务
  • day2 Linux操作系统指令
  • AI一周重要会议和活动概览