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

JavaScript concat方法疑问:为何第二次console.log非4元素数组

为什么第二次调用drawDeck后player1Hand没有变成4个元素?

这个问题的核心在于你对JavaScript函数参数传递的理解有点偏差,尤其是引用类型的处理方式。咱们一步步拆解你的代码问题:

首先看你的原始代码逻辑:

let player1Hand = [];
function drawDeck(whom, whichDeck, howMany) {
  whom = whom.concat(whichDeck.splice(0, howMany));
  console.log(whom);
}
drawDeck(player1Hand, genericDeck, 2);
drawDeck(player1Hand, genericDeck, 2);

问题出在哪?

JavaScript里函数参数是按值传递的——当你传递数组这种引用类型时,传递的是「引用的副本」,而不是引用本身。也就是说:

  • 第一次调用drawDeck时,whom拿到的是player1Hand(空数组)的引用副本。
  • 你执行whom = whom.concat(...)时,concat会返回一个新数组(包含原来的空数组加上splice出来的2个元素),然后你把这个新数组赋值给了函数内部的whom变量。但这只是修改了函数内部的whom,外部的player1Hand依然指向原来的空数组,完全没被影响。
  • 第二次调用drawDeck时,whom还是拿到空数组的引用副本,concat之后依然是2个元素的新数组,所以console.log输出的始终是2个元素,而外部的player1Hand从头到尾都是空的。

怎么解决?

有两种常用的修复方式,选哪种看你的需求:

方式1:直接修改原数组

既然你想让player1Hand本身被更新,那不要用concat返回新数组,而是直接往原数组里加元素。可以用push配合扩展运算符:

let player1Hand = [];
const genericDeck = [1,2,3,4,5,6]; // 假设genericDeck是这样的测试数组

function drawDeck(whom, whichDeck, howMany) {
  whom.push(...whichDeck.splice(0, howMany)); // 直接修改传入的原数组
  console.log(whom);
}

drawDeck(player1Hand, genericDeck, 2); // 输出: [1,2]
drawDeck(player1Hand, genericDeck, 2); // 输出: [1,2,3,4]

这里push(...xxx)会把splice出来的元素直接添加到whom指向的原数组里,而whom是player1Hand的引用,所以外部的player1Hand会同步更新。

方式2:让函数返回新数组,外部重新赋值

如果你不想修改原数组,而是每次生成新的手牌数组,那可以让函数返回新数组,然后外部把player1Hand重新赋值:

let player1Hand = [];
const genericDeck = [1,2,3,4,5,6];

function drawDeck(whom, whichDeck, howMany) {
  const newHand = whom.concat(whichDeck.splice(0, howMany));
  console.log(newHand);
  return newHand; // 返回新数组
}

player1Hand = drawDeck(player1Hand, genericDeck, 2); // 输出: [1,2]
player1Hand = drawDeck(player1Hand, genericDeck, 2); // 输出: [1,2,3,4]

这样每次调用函数都会生成新的手牌数组,然后把player1Hand指向这个新数组,自然就能累计元素了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:28:25