一个代码扫描规则引发的思考

事情的起因

最近需求开发完成后,在利用Sonar扫描代码的时候,在异味代码中居然发现了一条奇怪的规则。如下图:

起因就是我在代码中用了一个for循环类似这样for (let i = 0; i < rules.length; i++) {}然后代码扫描就提示了。

其实上面这条代码规则就是TypeScript tslint中的 "prefer-for-of" 规则。它旨在提醒开发者在迭代数组或可迭代对象时使用'for-of'循环而不是传统的'for'循环。那为什么推荐使用for-of而不是传统的for循环呢?下面我们详细讲解一下

for-of与for循环的区别

在日常开发中,遍历数组的时候我们很容易就想到ES6的forEach语法,但是如果我们需要提前中断循环,我们就需要for循环或者for-of循环了.但是for循环与for-of循环有什么区别呢?我们从下面几个维度去探讨一下:

语法复杂度

  • for 循环:语法较为繁琐,需手动管理计数器、循环条件和计数器更新。
  • for...of 循环:语法简洁,无需手动管理索引,直接迭代可迭代对象。
js 复制代码
const arr = [1, 2, 3];
// for-of
for (let item of arr) {
    console.log(item);
}

// for
for (let i = 0; i < arr.length; i++) {
    console.log(arr[i]);
}

可迭代对象支持

  • for 循环:一般用于数组的迭代,不过经过适当调整也能用于其他可索引的数据结构。要是迭代非数组对象,就需要手动处理索引。
  • for...of 循环:可以直接对任何可迭代对象进行迭代,像数组、字符串、Set、Map、NodeList 等。
js 复制代码
// for-of
const str = 'hello';
for (const char of str) {
    console.log(char);
}

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

// for
const obj = {0: 'a', 1: 'b', 2: 'c', length: 3};
for (let i = 0; i < obj.length; i++) {
    console.log(obj[i]);
}

索引访问

  • for 循环:能轻松访问当前元素的索引,在需要索引进行操作时非常有用,比如修改数组元素。
  • for...of 循环 :默认情况下只能获取元素的值,无法直接访问索引。若要获取索引,需要借助 entries() 方法。
ini 复制代码
// for-of
const arr = [1, 2, 3];
for (const [index, value] of arr.entries()) {
    console.log(`索引: ${index}, 值: ${value}`);
}

// for
const arr = [1, 2, 3];
for (let i = 0; i < arr.length; i++) {
    arr[i] = arr[i] * 2;
}
console.log(arr); 

稀疏数组处理

  • for 循环:会遍历数组的所有索引,包括那些没有赋值的索引,也就是会遍历稀疏数组的所有空位。
  • for...of 循环:只会遍历数组中实际存在的值,会跳过稀疏数组的空位。
js 复制代码
// for-of循环
const arr = [1, , 3];
for (const value of arr) {
    console.log(value); 
}

// for循环
const arr = [1, , 3];
for (let i = 0; i < arr.length; i++) {
    console.log(arr[i]); 
}

循环控制

  • for 循环:可通过修改计数器的值来灵活控制循环的执行,比如跳过某些元素或者重复执行某些操作。
  • for...of 循环 :不能直接控制循环的索引,只能过 breakcontinue 语句来控制循环的执行流程。
js 复制代码
//for-of
const arr = [1, 2, 3, 4, 5];
for (const value of arr) {
    if (value === 3) {
        continue; 
    }
    console.log(value);
}

// for循环
const arr = [1, 2, 3, 4, 5];
for (let i = 0; i < arr.length; i++) {
    if (arr[i] === 3) {
        i++; 
    }
    console.log(arr[i]);
}

总结一下,为什么要用for-of替代for循环

1.代码简洁性

  • for 循环:需要手动设置初始化变量、循环条件以及更新变量,代码结构相对复杂。例如遍历数组时,需要额外定义索引变量并管理其变化。
  • for...of 循环:无需手动管理索引,直接从可迭代对象中获取值,代码更简洁直观。

2.安全性

  • for 循环:手动管理索引容易出现错误,如索引越界、更新索引时出错等,可能导致意外的结果或程序崩溃。
  • for...of 循环:自动处理迭代过程,不会出现索引越界的问题,减少了因索引管理不当导致的错误。

3.可迭代对象支持范围广

  • for 循环:主要适用于数组等具有明确索引的数据结构,对于其他可迭代对象(如字符串、Set、Map 等)的处理需要额外的操作。
  • for...of 循环:可以直接用于各种可迭代对象,无需考虑对象的具体类型和索引结构,提高了代码的通用性和复用性。

4.处理稀疏数组更合理

  • for 循环:会遍历数组的所有索引,包括稀疏数组中未赋值的空位,可能导致不必要的处理。
相关推荐
一周七喜h15 分钟前
在Vue3和TypeScripts中使用pinia
前端·javascript·vue.js
weixin_3954489120 分钟前
main.c_cursor_0202
前端·网络·算法
摘星编程36 分钟前
用React Native开发OpenHarmony应用:Calendar日期范围选择
javascript·react native·react.js
东东5161 小时前
基于vue的电商购物网站vue +ssm
java·前端·javascript·vue.js·毕业设计·毕设
MediaTea1 小时前
<span class=“js_title_inner“>Python:实例对象</span>
开发语言·前端·javascript·python·ecmascript
雨季6661 小时前
Flutter 三端应用实战:OpenHarmony “微光笔记”——在灵感消逝前,为思想点一盏灯
开发语言·javascript·flutter·ui·dart
编码者卢布2 小时前
【Azure Stream Analytic】用 JavaScript UDF 解决 JSON 字段被转成 Record 的关键点
javascript·json·azure
梦梦代码精2 小时前
开源、免费、可商用:BuildingAI一站式体验报告
开发语言·前端·数据结构·人工智能·后端·开源·知识图谱
0思必得02 小时前
[Web自动化] Selenium执行JavaScript语句
前端·javascript·爬虫·python·selenium·自动化
程序员敲代码吗2 小时前
MDN全面接入Deno兼容性数据:现代Web开发的“一张图”方案
前端