JavaScript 循环结构注意事项
笔记哥 /
06-03 /
13点赞 /
0评论 /
837阅读
循环作为 `算法与数据结构` 中的基石,JS 与其他编程语言一样,都提供了多种循环结构用于处理数据。
### for 循环
事物的开端往往都是从最常用的开始,循环结构咱们从 `for` 循环说起。
语法:
```js
for (初始化; 条件; 增量) {
// ...
}
```
示例:
```js
// 增量每次 +1
for (let i = 0; i < 10; i++) {
console.log(i);
}
// 增量每次 +2
for (let i = 0; i < 10; i += 2) {
console.log(i);
}
```
性能优化:
在使用 for 循环遍历数组的时候,可以提前缓存数组长度,减少 `length` 的访问次数。
```js
const arr = ['前', '端', '路', '引'];
// 提前使用 len 缓存数组长度
for (let i = 0, len = arr.length; i < len; i++) {
console.log(arr[i]);
}
```
此示例中使用了 `let` 同时声明了多个变量,在常规的代码编写中,不建议这么使用,但在循环体这种特殊情况下,这么写也能接受。
```js
// 同时声明多个变量
let a = '前端路引', b = 2, c = true;
```
增量不一定要使用 `i++` 自增,也可以使用 `i--` 递减,或者使用 `i += 2` 步进,甚至可以是 `i += 10`。
### for in 循环
ES6 规范出现之前,只能使用 `for in` 循环遍历对象,但这哥们有个坑,不止会遍历对象自身属性,还能遍历原型链上可枚举属性。
```js
const obj1 = {
name: '前端路引',
age: 1,
'favorite-color': 'red',
}
for (let key in obj1) {
console.log(key, obj1[key]);
}
/*
// 输出结果
name 前端路引
age 1
favorite-color red
*/
```
看个遍历原型链例子:
```js
// 如果有兄弟不小心给对象的原型链上填了一笔
Object.prototype.test = '我是原型链上的测试属性';
const obj1 = {
name: '前端路引',
age: 1,
'favorite-color': 'red',
}
for (let key in obj1) {
console.log(key, obj1[key]);
}
/*
// 输出结果
name 前端路引
age 1
favorite-color red
test 我是原型链上的测试属性
*/
for (const key in obj1) {
if (obj.hasOwnProperty(key)) { // 过滤掉原型链属性
console.log(key, obj1[key]);
}
}
/*
// 输出结果
name 前端路引
age 1
favorite-color red
*/
```
如上所示,代码编写规范建议不要对 JS 自身的原型链做修改,扩展原型链虽然方便了一些对象操作,但实际上这是埋了雷的,不知道啥时候就会引爆!!
在使用 `for in` 循环也需要注意原型链的属性,必须使用 `hasOwnProperty` 方法来过滤掉原型链上的属性。
### for of 循环
由于 `for in` 的各种弊端,后来定规范的大佬们,就新增了一个 `for of` 循环用于遍历可迭代对象,比如:数组、字符串、Set、Map 等等。
```js
const obj1 = {
name: '前端路引',
age: 1,
'favorite-color': 'red',
}
// for of 循环
for (let [key, value] of Object.entries(obj1)) {
console.log(key, value);
}
/* // 以上 let [key, value] 使用了 解构赋值,其代码等于
for (let item of Object.entries(obj1)) {
const [key, value] = item;
console.log(key, value);
}
// 又等于
for (let item of Object.entries(obj1)) {
const key = item[0];
const value = item[1];
console.log(key, value);
}
*/
```
`for of` 无法直接遍历对象,需要遍历对象时,需使用内置方法 `Object.entries` 将对象转为数组,再使用 `for of` 遍历,或者使用 `Object.keys`/`Object.values` 将对象转为键/值数组再遍历。
相比于 `for in` 循环,`for of` 循环性能更好,也不用考虑原型链问题。
### while 循环
`while` 循环多用于不确定循环次数的应用场景,比如读取文件数据流,并不知道需要循环多少次才能读取完。
```js
let i = 0;
while (i < 3) {
console.log(i);
i++;
}
```
一般能用 for 循环的场景,都能使用 while 循环替代。
### do while 循环
这个循环可有意思了,不管条件是否满足,都会先跑一次循环体,再判断条件。
应用场景例子:必须让用户先输入,再判断条件,直到输入正确才继续。
```js
let userInput;
do {
userInput = prompt("请输入一个大于 10 的数字:");
} while (isNaN(userInput) || Number(userInput) <= 10);
console.log("有效输入:", userInput);
```
## 死循环
在使用循环遍历时候,需特别注意 `死循环` 问题,条件处理不好,就进入死循环,导致程序崩溃。
比如:
```js
let i = 0;
while (i < 3) {
console.log(i);
// i++; // 忘记修改 i 的值,导致进入死循环
}
```
## 善用退出循环
`continue` / `break` / `return` 三个关键字都可以用来处理循环逻辑,不同的是:
- `continue`:跳过当前循环,继续下一次循环。
- `break`:跳出当前循环,不再继续循环。
- `return`:跳出当前函数,不再继续执行。
continue 示例:
```js
function loop1 () {
for (let i = 0; i < 10; i++) {
if (i % 2 === 0) {
continue; // 跳过偶数次循环,只输出奇数次循环
}
console.log(i); // 输出 1 3 5 7 9
}
console.log('循环结束'); // 会执行
}
loop1()
```
break 示例:
```js
function loop2 () {
for (let i = 0; i < 10; i++) {
if (i === 5) {
break; // 在第 6 次循环退出
}
console.log(i); // 输出 0 1 2 3 4
}
console.log('循环结束'); // 会执行
}
loop2()
```
return 示例:
```js
function loop3 () {
for (let i = 0; i < 10; i++) {
if (i === 5) {
return; // 在第 6 次循环退出函数,不会执行循环体后面的代码
}
console.log(i); // 输出 0 1 2 3 4
}
console.log('循环结束'); // 此行代码不会执行
}
loop3()
```
三个退出循环关键字都可以用于所有的循环语句,不要局限于 for 循环~~
## 写在最后
如果说算法是程序的灵魂,那么循环可以算是算法的基石,很多常见的算法都需要使用循环实现,比如各种数组排序算法、查找算法、最短路径算法等等。
本文来自投稿,不代表本站立场,如若转载,请注明出处:http//www.knowhub.vip/share/2/3964
- 热门的技术博文分享
- 1 . ESP实现Web服务器
- 2 . 从零到一:打造高效的金仓社区 API 集成到 MCP 服务方案
- 3 . 使用C#构建一个同时问多个LLM并总结的小工具
- 4 . .NET 原生驾驭 AI 新基建实战系列Milvus ── 大规模 AI 应用的向量数据库首选
- 5 . 在Avalonia/C#中使用依赖注入过程记录
- 6 . [设计模式/Java] 设计模式之工厂方法模式
- 7 . 5. RabbitMQ 消息队列中 Exchanges(交换机) 的详细说明
- 8 . SQL 中的各种连接 JOIN 的区别总结!
- 9 . JavaScript 中防抖和节流的多种实现方式及应用场景
- 10 . SaltStack 远程命令执行中文乱码问题
- 11 . 推荐10个 DeepSeek 神级提示词,建议搜藏起来使用
- 12 . C#基础:枚举、数组、类型、函数等解析
- 13 . VMware平台的Ubuntu部署完全分布式Hadoop环境
- 14 . C# 多项目打包时如何将项目引用转为包依赖
- 15 . Chrome 135 版本开发者工具(DevTools)更新内容
- 16 . 从零创建npm依赖,只需执行一条命令
- 17 . 关于 Newtonsoft.Json 和 System.Text.Json 混用导致的的序列化不识别的问题
- 18 . 大模型微调实战之训练数据集准备的艺术与科学
- 19 . Windows快速安装MongoDB之Mongo实战
- 20 . 探索 C# 14 新功能:实用特性为编程带来便利
- 相关联分享
- JavaScript 中防抖和节流的多种实现方式及应用场景
- JavaScript 条件语句中善用 return 让代码更清晰
- JavaScript 3 种书写位置及 script 标签的正确存放位置
- JavaScript 的各种调试方法
- JavaScript 循环结构注意事项
- JavaScript 运算符 == 和 === 有什么区别?
- JavaScript 数据类型与类型转换
- 一个神奇的JS代码,让浏览器在新的空白标签页运行我们 HTML 代码(createObjectURL 的妙用)
- JavaScript 的应用领域
- JavaScript 单线程原理与异步编程机制
- JavaScript 各种对象定义与对象取值方法
- JavaScript 变量声明 var、let、const 区别
- JavaScript 各种数组定义与数组取值方法
- 使用Vite创建一个动态网页的前端项目