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
相关产品推荐
相关产品推荐

