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

为何适配器函数修改num数组?自定义push函数未保留原数组的原因

为什么适配器函数会修改我的num数组?

哈哈,这个问题我刚学JS的时候也踩过一模一样的坑!咱们一步步拆解问题出在哪:

核心问题:pushed()直接操作了全局变量num

你看你的pushed()函数里写的是num.push(1)——这里的num是全局作用域里的那个数组,不管你在push()函数里怎么处理nums参数,pushed()都直接去修改全局的原数组了,这当然会让num发生变化!

你在push()里的操作没起到作用

再看你在push()里的代码:

  • var orig = nums.map(x => x):这一步确实创建了原数组的副本,没问题。
  • nums = orig:这一步只是把函数内部的nums变量重新指向了副本,但这改变的只是函数内部的局部变量引用,对外部的全局num完全没有影响。因为JS里函数参数是按值传递的(这里的"值"是数组的引用地址),重新赋值参数不会改变外部的原变量。

怎么修复?

咱们把pushed()改成接收数组参数的形式,让它操作副本而不是全局变量:

var num = []
function push(nums) {
  // 用扩展运算符复制数组,比map更简洁直观
  var orig = [...nums]
  // 把副本传给pushed,让它操作这个副本
  var newNum = pushed(orig)
  return newNum
}
function pushed(arr) {
  arr.push(1)
  return arr
}
console.log("new", push(num)) // 输出: new [1]
console.log("old", num) // 输出: old []

或者更简单点,直接在push()里完成复制和添加操作,省掉pushed()也行:

var num = []
function push(nums) {
  // 复制原数组并添加元素,一步到位
  const newNum = [...nums, 1]
  return newNum
}
console.log("new", push(num)) // new [1]
console.log("old", num) // old []

关键知识点回顾

  • 尽量避免直接操作全局变量,通过参数传递数据能大幅减少这种意外的副作用。
  • JS里数组是引用类型,传递数组参数时传递的是引用地址,但重新赋值参数变量不会影响外部原数组;如果要修改数组但不污染原数组,必须先创建副本再操作(比如用扩展运算符[...arr]、arr.map()、Array.from(arr)等方法)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 12:22:53