You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Sonar报Remove this assignment of "k"问题原因及修复咨询

Sonar「Remove this assignment of "k"」告警修复方案

告警触发原因

这条Sonar规则的核心判定逻辑是:禁止在for循环的循环体内部手动修改循环计数器变量。你代码中写在splice后的--k、--l就是触发告警的直接原因。
这种在循环体内篡改计数器的写法属于典型的代码坏味道:可读性差,后续维护时很容易因为忽略计数器的额外修改,引入死循环、索引越界、遍历漏项等隐蔽bug,Sonar不是否定你的业务逻辑,是否定这种高风险的实现方式。
问题截图

注意:直接删除--k、--l确实会导致功能异常。因为数组调用splice删除元素后,后续元素会整体前移一位,如果不回退索引,下一轮循环计数器自增后会直接跳过被删位置的新元素,出现菜单权限漏过滤的问题。

正确修复方案

不需要保留手动修改计数器的写法,换用不会产生索引错位问题的遍历逻辑即可,两种常用方案如下,功能和原代码完全一致:

  • 方案1:倒序遍历(最小改动)
    从数组末尾往前遍历,删除元素时只会影响已经遍历过的尾部索引,不会干扰还没遍历到的前部元素,完全不需要手动修正计数器:
// 外层菜单倒序遍历
for (let k = this.side_list.length - 1; k >= 0; k--) {
  const currentMenu = this.side_list[k];
  if (this.allowedPageList.indexOf(currentMenu.route) === -1) {
    this.side_list.splice(k, 1);
    continue;
  }
  // 子菜单同样倒序遍历
  if (currentMenu.children?.length > 0) {
    for (let l = currentMenu.children.length - 1; l >= 0; l--) {
      if (this.allowedPageList.indexOf(currentMenu.children[l].route) === -1) {
        currentMenu.children.splice(l, 1);
      }
    }
  }
}
  • 方案2:使用filter生成新数组(推荐,可读性最高)
    直接用数组原生的filter方法做过滤,全程不需要手动操作索引,逻辑更直观,从根源上避免计数器误用的问题:
this.side_list = this.side_list.filter(menu => {
  // 外层菜单无权限直接过滤
  if (this.allowedPageList.indexOf(menu.route) === -1) {
    return false;
  }
  // 过滤子菜单
  if (menu.children?.length) {
    menu.children = menu.children.filter(
      child => this.allowedPageList.indexOf(child.route) !== -1
    );
  }
  return true;
});

两种写法都可以直接消除Sonar告警,同时不会破坏原有的侧边栏权限过滤逻辑。

内容的提问来源于stack exchange,提问作者Aurazo Script

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 22:15:49