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

为何for...of遍历数组时原数组未更新?两类titleCase函数差异解析

为什么titleCase1无法更新数组,而titleCase2可以?

核心原因很简单:for...of循环里的word是数组元素的副本,不是对原数组元素的引用,而for循环通过索引直接操作数组元素,所以能修改原数组。

咱们一步步拆解:

先看titleCase1的问题

function titleCase1(str) {
  let words = str.split(" ");
  for (let word of words) {
    // 这里的word是数组当前元素的"拷贝"
    word = word[0].toUpperCase() + word.slice(1);
  }
  return words.join(" ");
}

当你用for (let word of words)遍历数组时,每次循环的word变量都会拿到当前数组元素的值副本——因为字符串是JavaScript里的值类型,传递的时候是复制值而不是引用。

你在循环里给word赋值,只是改变了这个临时变量的内容,完全不会影响原数组words里的元素。循环结束后,words数组还是原来的样子,所以最后join出来的自然还是原字符串。

再看titleCase2为什么生效

function titleCase2(str) {
  let words = str.split(" ");
  for (let i = 0; i < words.length; i++) {
    // 直接通过索引修改数组的元素
    words[i] = words[i][0].toUpperCase() + words[i].slice(1);
  }
  return words.join(" ");
}

这里用的是传统的索引遍历,words[i]直接指向数组在索引i位置的元素。当你给words[i]赋值时,是直接修改了数组本身对应的位置,所以循环结束后,words数组里的每个元素都被更新成了首字母大写的版本,最后join自然能得到正确结果。

举个更直观的例子

let arr = ['apple', 'banana'];

// for...of遍历,修改临时变量,原数组不变
for (let item of arr) {
  item = item.toUpperCase();
}
console.log(arr); // 输出: ['apple', 'banana']

// 索引遍历,直接修改数组元素,原数组改变
for (let i = 0; i < arr.length; i++) {
  arr[i] = arr[i].toUpperCase();
}
console.log(arr); // 输出: ['APPLE', 'BANANA']

补充:如果是引用类型会怎样?

要是数组里存的是对象(引用类型),for...of里修改对象的属性是会影响原数组的,因为此时word拿到的是对象的引用。比如:

let arr = [{name: 'alice'}, {name: 'bob'}];
for (let obj of arr) {
  obj.name = obj.name.toUpperCase();
}
console.log(arr); // 输出: [{name: 'ALICE'}, {name: 'BOB'}]

但你的例子里是字符串(值类型),所以不存在这种情况~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:22:53