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

关于JavaScript递归函数capitalizeFirst的两处疑问求助

递归函数capitalizeFirst的疑问解答

原代码

function capitalizeFirst(arr) {
  if (arr.length === 1) {
    return [arr[0].toUpperCase()]
  }
  let res = capitalizeFirst(arr.slice(0, -1))
  res.push(arr.slice(arr.length - 1)[0].toUpperCase())
  return res
}

console.log(capitalizeFirst(['dog', 'car', 'horse']))

疑问点

  • 基准情况中为什么要返回[arr[0].toUpperCase()],而非直接返回arr[0].toUpperCase()?
  • 为什么要对arr进行两次slice操作:一次是let res = capitalizeFirst(arr.slice(0, -1)),另一次是res.push(arr.slice(arr.length - 1)[0].toUpperCase())?

疑问1解答

递归的核心要求是每一层调用的返回值类型必须统一,否则上层调用无法正确处理结果。

这个函数的目标是返回一个「所有元素首字母大写的数组」,如果基准情况直接返回字符串(arr[0].toUpperCase()),那递归到最底层时返回的是单个字符串,上层调用拿到这个字符串后执行res.push()就会直接报错——因为字符串没有push方法。

返回数组[arr[0].toUpperCase()],才能保证每一层递归都返回数组,上层可以正常用push把当前层处理的元素加进去,最终得到完整的结果数组。

疑问2解答

两次slice是递归拆解问题的关键,作用完全不同:

  1. 第一次arr.slice(0, -1):把原数组切掉最后一个元素,生成新数组传给下一层递归。比如原数组是['dog','car','horse'],第一次调用会传['dog','car']进去,直到数组只剩一个元素触发基准情况。这一步是把大问题拆成更小的子问题。
  2. 第二次arr.slice(arr.length - 1):取出原数组的最后一个元素(slice(arr.length-1)返回只包含最后一个元素的数组),用[0]提取出这个元素,转成首字母大写后push到递归返回的结果数组里。这一步是把当前层的处理结果合并到子问题的结果中。

其实第二次slice可以简化成arr[arr.length-1],效果完全一样,原代码这么写可能是个人习惯,但逻辑没问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 23:20:47