你真的能区分JavaScript中的for of和for in吗

简介: 你真的能区分JavaScript中的for of和for in吗

前言🍧🍧


最近在复习备战期末考试,已经有一顿时间没有更新文章了,今天在复习的空档期来水(更新)一期文章。今天主要讲的就是新手在初次学习JavaScript的时候可能会混淆的两个东西:for of和 for in


大致了解⭐️⭐️


对于初学者,我们或许只知道无论是for of 还是for in他们都有一个功能那就是遍历,至于具体的细节或许我们不是很清楚,那么接下来我们就来详细的区分一下for of 和for in他们之间的不同点和相同点。


首先介绍一下for of 👟👟


for of 是在es6中新加入的东西,如果说for of 给我们最直观的体现就是使用for of 去遍历数组的话,直接打印输出的是value值,这一点和for in打印输出的是索引值index是不同的,这是对于我们这些初学者最直观的感受。

其次for of 最本质的区别就是他不能用来直接遍历普通的对象,而只能遍历部署了iterator(迭代器)接口的类数组对象.

那么什么是iterator呢?

迭代器(Iterator)就是这样一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)

下面的例子正好说明for of 是不能遍历普通的对象的:

let obj2 = { x: 1,y: 2, z: 3,};
for (const value of obj2) {
  console.log(value);
}
//遍历时出错
//Uncaught TypeError: obj2 is not iterable

这是因为普通对象不是 可迭代对象,这里面提到的可迭代对象是一种实现了迭代器协议的对象,其中的迭代器协议要求对象部署了这个iterator,而这个方法是挂载在原型下Symbol(Symbol.iterator)方法,因此我们在使用for of 去处理比如说是数组的时候,其实就是调用了数组原型下的这个方法,每当调用这个方法之后,方法内部就会返回next方法,这就相当于是''指针'', 下次在调用的时候''指针''就后移动

对此,可能很多同学还是感觉蒙蒙的,这里举一个例子来说明:

let obj = {
  data: [1, 2, 3],
  // 这里给对象实现了一个迭代器方法
  [Symbol.iterator]() {
    let index = 0;
    const data = this.data;
    return {
      next() {
        if (index < data.length) {
          return {  value: data[index++], done: false, };
        } else {
          return { done: true };
        }
      },
    };
  },
};
for (const value of obj) {
  console.log(value);
}//1 2 3

在经过这样的处理之后,我们就给对象实现了迭代器的方法。这样我们就可以使用for of 来对这个obj对象的遍历,大家看完这段代码肯定是一头雾水,这主要是对Symbol.iteratornext方法的不了解,我就来简单的介绍一下这两个方法。

  • Symbol.iterator这个是什么呢?其实这个属性是一个函数,他的返回值是一个迭代器对象,我们在对象中定义这个属性之后,当我们使用for of 的时候,语言机制会去寻找一种方法,这个方法就是next方法,当我们在对象中使用这个属性的时候,其实就是覆盖了默认的迭代器,这样我们就可以实现自己的逻辑代码。
  • 其次我们要注意返回的迭代器对象:我们要知道,迭代器对象是要带有next方法的对象,而且这个next方法的返回值还必须是一个包含value和done的对象。其中value是当前值,而done表示是否全部遍历完成.
  • 那么迭代器一般是如何使用的呢?其实无论是数组,对象,集合或者是其他的数据结构,迭代器中都是提供了next方法,每次去调用这个next方法都会返回这个数据集合的下一个值,联想一下C语言中的''指针''移动,这也就解释了为什么这里面要有一个next方法了.
  • 所以这部分代码也就变的比较的好理解了,我们实现了了一个Symbol.iterator方法,然后在里面定义了索引index并获取到了data数组,接着我们就return一个迭代器对象,里面包含next方法,然后进行判断如果当前索引小于数组长度,那么就返回一个对象里面包含此时的value值和done,并且done为false,表明此时迭代并没有完成,否则就是最终返回一个done为true,表明此时迭代事件已经完成。

经过上面的处理大家也看到这样做是非常麻烦的,如果我们不想要通过这种方式去获取每一个值呢?那么我们只能来使用一些巧妙的手段来处理一下:我们要避免直接的去遍历对象,而是要通过某种方法来进行一个过渡的处理.

所以如果我们要使用for of来去迭代对象,那么我们只能通过一些手段来处理加工一下才可以

let sum = 0;
let obj3 = {x: 1,y: 2, z: 3,};
for (const value of Object.values(obj3)) {
  sum += value;
}
console.log(Object.values(obj3));//[1,2,3]
console.log(sum);//6

在这里面我们使用了Object.values方法来获取对象中的值,经过处理之后返回一个数组,里面是包含对象中值的数组.而像数组,Map。Set,字符串,这都是内置了迭代器的类型,因此可以使用for of来进行迭代处理。当然这里面我们还可以使用类似Object.entries()和Object.keys()等方法来处理,这里就不再展开.


接着说一下for in🚴‍♀🚴‍♀


在介绍完for of之后我们紧接着说一下for infor in最直接的体现就是它可以直接的遍历处理对象类型的数据,不需要像for of那样在给他增加一个迭代器属性,下面我就来介绍一下:

let obj4 = {
  hobby: "唱,跳,rap",
  name: "kun",
  sex: "男",
};
for (const key in obj4) {
  console.log("属性名" + key, "属性值" + obj4[key]);
}

采用这种方式就不会出现报错,可以正常的打印输出值。因此如果我们在实际场景中使用的时候一般处理对象肯定是要使用for in来处理,但是像是如果遇到字符串,map等等这些本身带有迭代器的类型我们就可以交给for of 来处理,具体场景具体说明。

同时这也应证了上面所说的使用for in 中打印的是key值,因此我们要想获取属性值要通过obj4[key]。

同样使用for in我们也可以处理类似像map,set,string等类型的数据。但是和for of 最显著的区别还是我们可以直接处理对象.


总结👨‍🎓👨‍🎓


这里面我们解释了为什么for of 不能用来处理普通的对象,以及如何去处理,并且介绍了每种方法适合用来解决的问题,因此我们在使用的时候要根据具体的场景来具体的分析处理.

相关文章
|
Java API 开发者
Spring中@import注解终极揭秘
在Spring框架中,@Import注解可以用来引入一个或多个组件,这些组件通常是通过@Bean注解定义的,当使用@Import注解时,实际上是在告诉Spring:“除了当前配置类中的bean定义外,还想包含另一个配置类(或多个配置类)中定义的bean。”
226 1
Spring中@import注解终极揭秘
|
虚拟化 索引
看一下ARM的IP:SMMUU
看一下ARM的IP:SMMUU
698 1
|
开发框架 关系型数据库 PHP
Laravel
Laravel 是一款基于 PHP 的 Web 应用程序开发框架,它具有简洁、优雅的语法,强大的功能,以及丰富的组件,让开发者能够快速、高效地开发出功能丰富、性能优良的 Web 应用。要用 Laravel,首先需要安装 Laravel。
291 2
|
12月前
|
机器学习/深度学习 自然语言处理 测试技术
CoT神话破灭,并非LLM标配!三大学府机构联手证实,CoT仅在数学符号推理有用
【10月更文挑战第17天】链式思维(CoT)曾被认为是大型语言模型(LLM)激发推理能力的关键方法,但最新研究显示,CoT仅在数学和符号推理任务中有效,其他任务中效果不明显。加州大学伯克利分校、斯坦福大学和卡内基梅隆大学的联合研究打破了CoT作为LLM标配的神话,为重新评估LLM的推理能力提供了新视角。
261 1
|
8月前
|
人工智能 编解码 算法
ENEL:3D建模革命!上海AI Lab黑科技砍掉编码器,7B模型性能吊打13B巨头
ENEL是由上海AI Lab推出的无编码器3D大型多模态模型,能够在多个3D任务中实现高效语义编码和几何结构理解,如3D对象分类、字幕生成和视觉问答。
218 9
ENEL:3D建模革命!上海AI Lab黑科技砍掉编码器,7B模型性能吊打13B巨头
|
11月前
|
网络安全 Nacos 开发者
Nacos作为流行的微服务注册与配置中心,“节点提示暂时不可用”是常见的问题之一
Nacos作为流行的微服务注册与配置中心,其稳定性和易用性备受青睐。然而,“节点提示暂时不可用”是常见的问题之一。本文将探讨该问题的原因及解决方案,帮助开发者快速定位并解决问题,确保服务的正常运行。通过检查服务实例状态、网络连接、Nacos配置、调整健康检查策略等步骤,可以有效解决这一问题。
244 4
|
XML Android开发 数据格式
🌐Android国际化与本地化全攻略!让你的App走遍全球无障碍!🌍
在全球化背景下,实现Android应用的国际化与本地化至关重要。本文以一款旅游指南App为例,详细介绍如何通过资源文件拆分与命名、适配布局与方向、处理日期时间及货币格式、考虑文化习俗等步骤,完成多语言支持和本地化调整。通过邀请用户测试并收集反馈,确保应用能无缝融入不同市场,提升用户体验与满意度。
472 3
|
机器学习/深度学习 存储 人工智能
【AI】告别繁琐阅读,阿里通义智文阅读助手带您轻松畅游知识海洋!
阿里通义智文阅读助手是AI驱动的阅读辅助工具,能识别并解析PPT、图片、PDF等文档,提供摘要、关键词提取、语义理解与问答功能。用户可上传图片文件,工具自动识别文字,支持图表识别和全文搜索。此外,它还具有智能问答功能,能回答用户关于文档内容的问题。工具兼容多种文件格式,但有每日使用和存储限制。作者木头左邀请用户体验并期待下次分享。
【AI】告别繁琐阅读,阿里通义智文阅读助手带您轻松畅游知识海洋!
|
人工智能
魔搭多模态AI单词助记&通义APP即时口语练习,你从未体验过的全新版本!
首次接触魔搭多模态AI单词助记工具让我颇感惊喜。传统背单词方式枯燥低效,而该工具通过生成关联图像、短语或故事,让记忆变得生动有趣。访问[Word-wizard](https://modelscope.cn/studios/makabakaing/Word-wizard)体验其图文记忆和视觉学习功能。目前图文记忆功能似乎存在问题,但视觉学习功能仍可正常使用,能识别图片特征并生成释义和例句,辅助学习效果不错。此外,可通过通义APP实现即时口语练习,尽管缺乏上下文记忆功能,但仍是一个优秀的练习工具。
|
运维 调度 数据库
快讯~数据推送已上架 DataStudio 数据开发,与工作流完美结合
数据推送日前已在数据服务页面上提供全托管式的推送服务,基于同样的底层推送架构,我们将推送的能力也搬上了数据开发 (DataStudio),结合数据开发已有的工作流,提供了简单推送、合并推送、脚本推送及条件推送等四大推送能力,用户能在既有的工作流上弹性组装四种方式的推送。
210 0
快讯~数据推送已上架 DataStudio 数据开发,与工作流完美结合