【Javascript】关于如何使用循环,看这篇就够了

2024-08-21 10:20
文章标签 java 使用 script 循环 这篇

本文主要是介绍【Javascript】关于如何使用循环,看这篇就够了,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

每种编程语言都有循环。循环执行某个操作(也就是一段工作)多次,通常是对数组或列表中的每一项进行操作,或者重复执行直到满足某个条件为止。

JavaScript 尤其提供了多种不同类型的循环。我自己甚至都没有用过所有这些类型,出于好奇心,我想做个高层次的概览。结果发现,至少有几种循环类型没被广泛采用是有充分理由的。

那么,咱们就先用 for 循环开始,花点 while 时间来探索各种不同的循环类型,看看我们能用 each 做些什么,以及为什么你可能会选择一种而非另一种。读到最后你会觉得我这里的小文字游戏绝对逗乐。

whiledo...while 循环

首先登场的是 while 循环。这是最基础的循环类型,在很多情况下也是最容易阅读和最快的。它通常用于做某件事直到满足某个条件。这也是最容易制造无限循环或永不停止的循环的方式。还有 do...while 语句。实际上,唯一的区别在于条件是在每次迭代的末尾而不是开头检查。

// 从数组中移除第一个元素并打印出来,直到数组为空
let queue1 = ["a", "b", "c"];while (queue1.length) {let item = queue1.shift();console.log(item);
}// 上面的相同逻辑,但也会打印数组为空时的信息
let queue2 = [];do {let item = queue2.shift() ?? "empty";console.log(item);
} while (queue2.length);

for 循环

接下来是 for 循环。如果你需要重复执行某个操作一定次数,比如十次,那这就是首选。这种循环对编程新手来说可能有点吓人,但是把相同的循环用 while 风格重写一下,可以帮助理解语法,也更容易记住。

// 打印数字 1 到 5
for (let i = 1; i <= 5; i++) {console.log(i);
}// 同样的事情,但是用 `while` 循环实现
let i = 1; // `for` 循环的第一部分// 第二部分
while (i <= 5) {console.log(i);i++; // 第三部分
}("end");

for...offor await...of 循环

for...of 循环是最简单的方式来遍历数组。

let myList = ["a", "b", "c"];for (let item of myList) {console.log(item);
}

不过它们不仅仅限于数组。技术上讲,它们可以遍历实现了所谓的 可迭代协议 的任何东西。有一些内置类型实现了该协议:数组、映射、集合和字符串,这些是最常见的,但你也可以在自己的代码中实现该协议。做法是在任意对象中添加一个 [Symbol.iterator] 方法,而这个方法应该返回一个迭代器。这有点让人困惑,但大概意思是可迭代的对象是一种特殊的方法,返回迭代器;可以说是迭代器的工厂方法。一种特殊的函数叫做 生成器,它既能返回可迭代对象也能返回迭代器。

let myList = {*[Symbol.iterator]() {yield "a";yield "b";yield "c";},
};for (let item of myList) {console.log(item);
}

上面提到的所有东西都有异步版本:异步可迭代对象、异步迭代器和异步生成器。你可以用 for await...of 来使用异步可迭代对象。

async function delay(ms) {return new Promise((resolve) => {setTimeout(resolve, ms);});
}// 这次我们不是创建一个可迭代对象,而是生成器
async function* aNumberAMinute() {let i = 0;while (true) {// an infinite loopyield i++;// pause a minuteawait delay(60_000);}
}// 它是一个生成器,所以我们需要自己调用它
for await (let i of aNumberAMinute()) {console.log(i);// stop after one hourif (i >= 59) {break;}
}

有一点不太明显的是,你可以用非异步可迭代对象与 for await...of 一起使用,而且完全没问题。然而反过来就不行;你不能用异步可迭代对象与 for...of 一起使用。

forEachmap “循环”

虽然这些严格意义上不算循环,但你可以用它们来遍历列表。

说说 forEach 方法吧。历史上它的速度远不如 for 循环。我认为现在有些情况下这种情况可能已经改变,但如果性能是个问题,我还是会避免使用它。有了 for...of 之后,我不确定还有什么理由要用它。也许唯一的原因是你已经有了一个可以直接作为回调使用的函数,但你也可以很容易地在 for...of 的主体里调用同一个函数。

forEach 还接收每个元素的索引,所以这可能是你需要的功能。最终是否使用它,可能会取决于你正在处理的其他代码是否也在使用它,但如果是新写的代码我个人会尽量避免使用它。

let myList = ["a", "b", "c"];for (let item of myList) {console.log(item);
}// 如果我需要索引,或许可以用 `forEach`
["a", "b", "c"].forEach((item, index) => {console.log(`${index}: ${item}`);
});

同时,map 实质上是将一个数组转换为另一个数组。它与 forEach 一样有性能影响,但它比替代方案更好读一点。当然这是主观判断,就像 forEach 一样,你会希望遵循你的其他代码的做法。在 React 和受 React 启发的库中,你会经常看到它作为遍历数组并在 JSX 中输出项目列表的主要方式。

function MyList({items}) {return (<ul>{items.map((item) => {return <li>{item}</li>;})}</ul>);
}

for...in 循环

说到 JavaScript 中的循环,如果不提 for...in 语句,这个列表就不完整了,因为它可以遍历对象的字段。它还会遍历通过对象原型链继承的字段,这正是我一直避免使用它的原因。

话虽如此,如果你有一个对象字面量,那么 for...in 可能是遍历该对象键的有效方式。值得一提的是,如果你编写 JavaScript 已经有一段时间了,你可能还记得键的顺序曾经在不同浏览器之间不一致,但现在顺序是一致的。任何可能作为数组索引的键(即正整数)都会按升序排列在前面,然后是按声明顺序排列的其他键。

let myObject = {a: 1,b: 2,c: 3,
};for (let k in myObject) {console.log(myObject[k]);
}

结语

循环是许多程序员每天都在使用的东西,尽管我们可能会习以为常,不太去思考它们。

但当你退一步来看我们在 JavaScript 中遍历事物的各种方式时,你会发现其实有很多种方法可以做到这一点。不仅如此,它们之间存在显著——即使细微——的区别,这些差异确实会影响你的编写方式。

这篇关于【Javascript】关于如何使用循环,看这篇就够了的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1092886

相关文章

使用Navicat工具比对两个数据库所有表结构的差异案例详解

《使用Navicat工具比对两个数据库所有表结构的差异案例详解》:本文主要介绍如何使用Navicat工具对比两个数据库test_old和test_new,并生成相应的DDLSQL语句,以便将te... 目录概要案例一、如图两个数据库test_old和test_new进行比较:二、开始比较总结概要公司存在多

JavaWeb-WebSocket浏览器服务器双向通信方式

《JavaWeb-WebSocket浏览器服务器双向通信方式》文章介绍了WebSocket协议的工作原理和应用场景,包括与HTTP的对比,接着,详细介绍了如何在Java中使用WebSocket,包括配... 目录一、概述二、入门2.1 POM依赖2.2 编写配置类2.3 编写WebSocket服务2.4 浏

配置springboot项目动静分离打包分离lib方式

《配置springboot项目动静分离打包分离lib方式》本文介绍了如何将SpringBoot工程中的静态资源和配置文件分离出来,以减少jar包大小,方便修改配置文件,通过在jar包同级目录创建co... 目录前言1、分离配置文件原理2、pom文件配置3、使用package命令打包4、总结前言默认情况下,

Java文件与Base64之间的转化方式

《Java文件与Base64之间的转化方式》这篇文章介绍了如何使用Java将文件(如图片、视频)转换为Base64编码,以及如何将Base64编码转换回文件,通过提供具体的工具类实现,作者希望帮助读者... 目录Java文件与Base64之间的转化1、文件转Base64工具类2、Base64转文件工具类3、

java获取图片的大小、宽度、高度方式

《java获取图片的大小、宽度、高度方式》文章介绍了如何将File对象转换为MultipartFile对象的过程,并分享了个人经验,希望能为读者提供参考... 目China编程录Java获取图片的大小、宽度、高度File对象(该对象里面是图片)MultipartFile对象(该对象里面是图片)总结java获取图片

CSS3中使用flex和grid实现等高元素布局的示例代码

《CSS3中使用flex和grid实现等高元素布局的示例代码》:本文主要介绍了使用CSS3中的Flexbox和Grid布局实现等高元素布局的方法,通过简单的两列实现、每行放置3列以及全部代码的展示,展示了这两种布局方式的实现细节和效果,详细内容请阅读本文,希望能对你有所帮助... 过往的实现方法是使用浮动加

Java通过反射获取方法参数名的方式小结

《Java通过反射获取方法参数名的方式小结》这篇文章主要为大家详细介绍了Java如何通过反射获取方法参数名的方式,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1、前言2、解决方式方式2.1: 添加编译参数配置 -parameters方式2.2: 使用Spring的内部工具类 -

Java如何获取视频文件的视频时长

《Java如何获取视频文件的视频时长》文章介绍了如何使用Java获取视频文件的视频时长,包括导入maven依赖和代码案例,同时,也讨论了在运行过程中遇到的SLF4J加载问题,并给出了解决方案... 目录Java获取视频文件的视频时长1、导入maven依赖2、代码案例3、SLF4J: Failed to lo

如何使用Spring boot的@Transactional进行事务管理

《如何使用Springboot的@Transactional进行事务管理》这篇文章介绍了SpringBoot中使用@Transactional注解进行声明式事务管理的详细信息,包括基本用法、核心配置... 目录一、前置条件二、基本用法1. 在方法上添加注解2. 在类上添加注解三、核心配置参数1. 传播行为(

在Java中使用ModelMapper简化Shapefile属性转JavaBean实战过程

《在Java中使用ModelMapper简化Shapefile属性转JavaBean实战过程》本文介绍了在Java中使用ModelMapper库简化Shapefile属性转JavaBean的过程,对比... 目录前言一、原始的处理办法1、使用Set方法来转换2、使用构造方法转换二、基于ModelMapper