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

JavaScript循环跳过特定索引:字符串排列代码为何遗漏第二个字符?

问题原因分析:全局循环变量导致的逻辑错误

嘿,我一眼就发现问题所在了——你的代码里的循环变量i和j都没有用块级作用域声明,全部变成了全局变量,这就是循环跳过第二个字符的核心原因!

具体问题拆解

我们来看代码里的几个循环:

  1. addNew函数内的for(i=0;i<=arr.length;i++):这里的i没有用var/let/const声明,会自动挂载到全局作用域。
  2. 外层的for(i=0;i<chars.length;i++):同样使用了未声明的全局i。
  3. 内层的for(j=0;j<temp.length;j++):j也是未声明的全局变量。

当代码执行到第一次外层循环(处理第一个字符)时,会调用addNew函数,而addNew里的循环会修改全局的i值。等addNew执行完毕,全局i已经被更新到超出当前外层循环的预期值了——比如处理"abcd"的第一个字符'a'时,addNew里的循环结束后i会变成1,此时外层循环的i++会直接把i变成2,跳过了i=1的循环(也就是第二个字符'b'完全没被处理)。

后续循环只会处理第三个、第四个字符,最终生成的排列自然就缺少了包含第二个字符的所有组合。

修复方案:给循环变量添加块级作用域

只需要把所有循环变量用let声明(let会创建块级作用域,每个循环的变量都是独立的,不会互相干扰),代码就能正常工作了:

function perm(str){
  function addNew(arr,char){
    var result =[];
    // 用let声明块级作用域的i
    for(let i=0;i<=arr.length;i++){
      var temp =[...arr];
      temp.splice(i,0,char);
      result.push(temp);
    }
    return result;
  }
  var chars =str.split("");
  var results =[[]];
  // 用let声明块级作用域的i
  for(let i=0;i<chars.length;i++){
    var temp =[...results];
    results =[];
    // 用let声明块级作用域的j
    for(let j=0;j<temp.length;j++){
      results =[...results,...addNew(temp[j],chars[i])];
    }
  }
  return results;
}

现在调用perm("abcd")就能得到所有24个完整的排列了~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:29:32