for...in、for...of、for...Each的详细区别!

for...in

for...in 语句以任意顺序迭代一个对象的除Symbol以外的可枚举属性,包括继承的可枚举属性。

仅迭代自身的属性

如果你只要考虑对象本身的属性,而不是它的原型,那么使用 getOwnPropertyNames() 或执行 hasOwnProperty() 来确定某属性是否是对象本身的属性(也能使用propertyIsEnumerable)。或者,如果你知道不会有任何外部代码干扰,你可以使用检查方法扩展内置原型。

为什么用 for ... in?

for ... in是为遍历对象属性而构建的,不建议与数组一起使用,数组可以用Array.prototype.forEach()for ... of,那么for ... in的到底有什么用呢?

它最常用的地方应该是用于调试,可以更方便的去检查对象属性(通过输出到控制台或其他方式)。尽管对于处理存储数据,数组更实用些,但是你在处理有key-value数据(比如属性用作“键”),需要检查其中的任何键是否为某值的情况时,还是推荐用for ... in

示例

下面的函数接受一个对象作为参数。被调用时迭代传入对象的所有可枚举属性然后返回一个所有属性名和其对应值的字符串。

var obj = { a: 1, b: 2, c: 3 };for (var prop in obj) {console.log("obj." + prop + " = " + obj[prop]);
}// Output:
// "obj.a = 1"
// "obj.b = 2"
// "obj.c = 3"

for...of

for...of语句在可迭代对象(包括 Array,Map,Set,String,TypedArray,arguments 对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句

语法 

for (variable of iterable) {//statements
}

 示例

let iterable = [10, 20, 30];for (let value of iterable) {value += 1;console.log(value);
}
// 11
// 21
// 31

如果你不想修改语句块中的变量 , 也可以使用const代替let。

let iterable = [10, 20, 30];for (const value of iterable) {console.log(value);
}
// 10
// 20
// 30

 迭代String

let iterable = "boo";for (let value of iterable) {console.log(value);
}
// "b"
// "o"
// "o"

 迭代 TypedArray

let iterable = new Uint8Array([0x00, 0xff]);for (let value of iterable) {console.log(value);
}
// 0
// 255

 迭代Map

 

let iterable = new Map([["a", 1],["b", 2],["c", 3],
]);for (let entry of iterable) {console.log(entry);
}
// ["a", 1]
// ["b", 2]
// ["c", 3]for (let [key, value] of iterable) {console.log(value);
}
// 1
// 2
// 3

迭代 Set

let iterable = new Set([1, 1, 2, 2, 3, 3]);for (let value of iterable) {console.log(value);
}
// 1
// 2
// 3

 迭代 arguments 对象

(function () {for (let argument of arguments) {console.log(argument);}
})(1, 2, 3);// 1
// 2
// 3

forEach()    Array.prototype.forEach()

forEach() 方法对数组的每个元素执行一次给定的函数。

描述

forEach() 方法是一个迭代方法。它按索引升序地为数组中的每个元素调用一次提供的 callbackFn 函数。与 map() 不同,forEach() 总是返回 undefined,而且不能继续链式调用。其典型的用法是在链式调用的末尾执行某些操作。

callbackFn 仅对已赋值的数组索引调用。对于稀疏数组中的空槽,它不会被调用。

forEach() 不会改变其调用的数组,但是,作为 callbackFn 的函数可以更改数组。请注意,在第一次调用 callbackFn 之前,数组的长度已经被保存。因此:

  • 当调用 forEach() 时,callbackFn 不会访问超出数组初始长度的任何元素。
  • 已经访问过的索引的更改不会导致 callbackFn 再次调用它们。
  • 如果 callbackFn 更改了数组中已经存在但尚未访问的元素,则传递给 callbackFn 的值将是在访问该元素时的值。已经被删除的元素不会被访问。

警告: 上述类型的并发修改经常导致难以理解的代码,通常应避免(特殊情况除外)。

forEach() 方法是通用的。它只期望 this 值具有 length 属性和整数键的属性。

除非抛出异常,否则没有办法停止或中断 forEach() 循环。如果有这样的需求,则不应该使用 forEach() 方法。

可以通过像 for、for...of 和 for...in 这样的循环语句来实现提前终止。当不需要进一步迭代时,诸如 every()、some()、find() 和 findIndex() 等数组方法也会立即停止迭代。

forEach() 期望的是一个同步函数,它不会等待 Promise 兑现。在使用 Promise(或异步函数)作为 forEach 回调时,请确保你意识到这一点可能带来的影响。

const ratings = [5, 4, 5];
let sum = 0;const sumFunction = async (a, b) => a + b;ratings.forEach(async (rating) => {sum = await sumFunction(sum, rating);
});console.log(sum);
// 期望的输出:14
// 实际的输出:0

将 for 循环转换为 forEach

const items = ["item1", "item2", "item3"];
const copyItems = [];// before
for (let i = 0; i < items.length; i++) {copyItems.push(items[i]);
}// after
items.forEach((item) => {copyItems.push(item);
});

 总而言之,言而总之
 

for...in

  • 用于遍历对象的属性。

  • 返回的是属性名。

  • 它不会按照插入顺序遍历属性,并且可能不会遍历到原型链上的属性。

  • 示例:

let obj = { a: 1, b: 2, c: 3 };  
for (let key in obj) {  console.log(key); // 输出 "a", "b", "c"  
}`

 

for...of

  • 用于遍历可迭代对象(如数组、Map、Set 等)。

  • 返回的是迭代器的值。

  • 可以与 yield 关键字结合使用在生成器函数中。

  • 示例:

let arr = [1, 2, 3];  
for (let value of arr) {  console.log(value); // 输出 "1", "2", "3"  
}`

 

forEach

  • 用于遍历数组。

  • 返回的是 undefined。

  • 它的参数包括当前值、当前索引和数组本身。

  • 它与 for...of 的主要区别在于它不能用于非数组的可迭代对象。

  • 示例:

let arr = [1, 2, 3];  
arr.forEach((value, index, array) => {  console.log(value); // 输出 "1", "2", "3"  console.log(index); // 输出 "0", "1", "2"  console.log(array); // 输出整个数组 [1, 2, 3]  
});`

它们都可以遍历数组和对象,但不能遍历基本类型(如字符串、数字、布尔值)或 nullundefined。如果你尝试对它们使用 for...infor...of 或 forEach,JavaScript 会抛出错误。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/638852.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

excel统计分析——Tukey法多重比较

参考资料&#xff1a;生物统计学 https://real-statistics.com/one-way-analysis-of-variance-anova/unplanned-comparisons/tukey-hsd/ Tukey法是基于学生化极差分布计算最小显著极差&#xff08;LSR&#xff09;&#xff0c;根据平均数个数调整最小显著极差。 LSR&#xff1…

Steam++(Watt Toolkit)加速GitHub失效特殊情况

github无法访问有很多情况&#xff0c;网上已经有很多解决方法&#xff0c;这里说一种特殊情况 如果你满足下列条件&#xff1a; 1、使用过Steam&#xff08;Watt Toolkit&#xff09;加速GitHub&#xff1b; 2、某天突然发现Steam&#xff08;Watt Toolkit&#xff09;对GitH…

LINUX常用工具之sudo权限控制

一、Sudo基本介绍 sudo是Linux 中用于允许特定用户以超级用户或其他特权用户的身份执行特定的命令或任务。sudo 提供了一种安全的方法&#xff0c;使用户能够临时获取额外的权限&#xff0c;而不需要以完全超级用户的身份登录系统。sudo也可以用了设置黑名单命令清单&#xff…

ROS第 13 课 TF 坐标系广播与监听的编程 实现

文章目录 第 13 课 TF 坐标系广播与监听的编程 实现1.机器人的坐标变换2.创建功能包3.编程方法3.1 编写广播和监听程序3.2 运行程序 第 13 课 TF 坐标系广播与监听的编程 实现 1.机器人的坐标变换 在进行编程前&#xff0c;先需要了解机器人的坐标变换。这里以运行海龟案例来…

体验开源香山高性能开源 RISC-V 处理器

整体架构设计 香山处理器是乱序六发射结构设计&#xff0c;目前支持 RV64GCBK 扩展。香山处理器前端流水线包括分支预测单元、取指单元、指令缓冲等单元&#xff0c;顺序取指。后端包括译码、重命名、重定序缓冲、保留站、整型/浮点寄存器堆、整型/浮点运算单元。 doc https…

有关软件测试的,任何时间都可以,软件测试主要服务项目:测试用例 报告 计划

有关软件测试的&#xff0c;任何时间都可以&#xff0c;软件测试主要服务项目&#xff1a; 1. 测试用例 2. 测试报告 3. 测试计划 4. 白盒测试 5. 黑盒测试 6. 接口测试 7.自动…

Vuex的基础使用

在使用之前要先了解Vuex的组成结构&#xff0c;跟对应的使用关系。 在上图的结构图中可以看到四个组成部分&#xff0c;首先是Components&#xff08;组件&#xff09;、Actions&#xff08;行动&#xff09;、Mutations&#xff08;变化&#xff09;、state&#xff08;状态/数…

Vue——计算属性

文章目录 计算属性computed 计算属性 vs methods 方法计算属性完整写法 综合案例&#xff1a;成绩案例 计算属性 概念&#xff1a;基于现有的数据&#xff0c;计算出来的新属性。依赖的数据变化&#xff0c;自动重新计算 语法: ①声明computed配置项中&#xff0c;一个计算属性…

清华大学计算机学科推荐学术会议和期刊列表——网络与信息安全

A类会议 这里仅列出A类会议 会议简称会议全程网址IEEE S&PIEEE Symposium on Security and Privacyhttp://dblp.uni-trier.de/db/conf/sp/NDSSISOC Network and Distributed System Security Symposiumhttp://dblp.uni-trier.de/db/conf/ndss/USENIX SecurityUsenix Secu…

nodejs学习计划--(三)http协议和IP介绍

一、 HTPP协议 1、概念 HTTP&#xff08;hypertext transport protocol&#xff09;协议&#xff1b;中文叫超文本传输协议 是一种基于TCP/IP的应用层通信协议 这个协议详细规定了 浏览器 和万维网 服务器 之间互相通信的规则。 协议中主要规定了两个方面的内容 客户端&…

gin渲染篇

1. 各种数据格式的响应 json、结构体、XML、YAML类似于java的properties、ProtoBuf package mainimport ("github.com/gin-gonic/gin""github.com/gin-gonic/gin/testdata/protoexample" )// 多种响应方式 func main() {// 1.创建路由// 默认使用了2个中…

链表中倒数第k个结点(附带源码)

目录 代码部分&#xff1a; 核心&#xff1a;看图 代码部分&#xff1a; struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {// write code here// write code hereif (k 0){return NULL;}else{struct ListNode* slow pListHead, * fast pListHead;//…

C++中函数的默认参数(缺省参数)

一、函数默认参数的概念 在函数声明时&#xff0c;预先对函数参数进行赋值&#xff0c;该参数即为函数的默认参数&#xff0c;也叫缺省参数。 如下函数func1包含默认参数&#xff0c;若调用函数func1时没有给函数传入实参&#xff0c;则默认实参为10086 void func1(int a 1…

【Redis】Ubuntu安装配置

目录 一、安装Redis 1.1 从APT仓库安装Redis 二、启动&关闭&重启 三、Redis核心配置 3.1 CONFIG命令 3.2 redis.conf文件说明 一、安装Redis 1.1 从APT仓库安装Redis 从APT仓库可以安装最新的Redis稳定版&#xff0c;步骤如下&#xff1a; 【1】安装需要用到的…

Spring 中有哪些方式可以把 Bean 注入到 IOC 容器?

目录 1、xml方式2、CompontScan Component3、使用 Bean方式4、使用Import 注解5、FactoryBean 工厂 bean6、使用 ImportBeanDefinitionRegistrar 向容器中注入Bean7、实现 ImportSelector 接口 1、xml方式 使用 xml 的方式来声明 Bean 的定义&#xff0c;Spring 容器在启动的…

Linux内核pinctrl子系统驱动框架

一. 简介 本文简单了解一下Linux内核代码中&#xff0c; pinctrl子系统的驱动实现。 注意&#xff1a;本文会涉及到 Linux 驱动分层与分离、平台设备驱动等还未讲解的知识 &#xff0c;所以&#xff0c;也不会影响后续的实验。 二. Linux内核pinctrl子系统驱动 1. probe函…

【数学建模】数据处理与可视化

文章目录 数值计算工具NumPy数组的创建、属性和操作数组的运算、通用函数和广播运算Numpy.random模块的随机数生成文本文件和二进制文件存取 文件操作文件基本操作文件管理方法 数据处理工具PandasSeries和DataFrame外部文件存取 Matplotlib可视化基础用法可视化应用可视化综合…

2023年DevOps国际峰会暨 BizDevOps 企业峰会(DOIS北京站):核心内容与学习收获(附大会核心PPT下载)

随着科技的飞速发展&#xff0c;软件开发的模式和流程也在不断地演变。在众多软件开发方法中&#xff0c;DevOps已成为当下热门的软件开发运维一体化模式。特别是在中国&#xff0c;随着越来越多的企业开始认识到DevOps的价值&#xff0c;这一领域的研究与实践活动日益活跃。本…

互联网架构演变过程

互联网架构演变过程 互联网架构经历了几个重要的演变过程&#xff0c;主要包括以下几个阶段&#xff1a; 单一服务器架构&#xff1a;早期的互联网应用通常运行在单一的服务器上&#xff0c;该服务器负责处理所有的请求和数据存储。这种架构简单直接&#xff0c;但容易出现性能…

反序列化字符串逃逸(下篇)

这里承接上篇文章反序列化字符串逃逸&#xff08;上篇&#xff09;-CSDN博客带大家学习反序列化字符串逃逸减少&#xff0c;没有看过的可以先去看看&#xff0c;不会吃亏。 例题&#xff1a; <?php highlight_file(__FILE__); error_reporting(0); function filter($name…