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

修改对象属性值时如何不改变原对象?(卡牌数组场景)

卡牌排序与转换后数组内容一致的问题

现有卡牌数组cardsHand,需要生成两个目标数组:

  • sortedCardsByValue:排序后保留原数值的数组
  • convertedCards:排序后将数值转换为对应牌面(1→A、11→J、12→Q、13→K)的数组

但当前代码生成的两个数组完全相同,尝试map、forEach等方法仍未解决问题。

原代码

cardsHand = [
{ value: "1", suit: "C" },
{ value: "13", suit: "C" },
{ value: "12", suit: "C" },
{ value: "11", suit: "C" },
{ value: "10", suit: "C" },
];

function sortCards(cardsHand) {
//SORT VALUES
let sortedCardsByValue = [];
sortedCardsByValue = cardsHand.sort(
(currCardA, currCardB) => currCardA.value - currCardB.value);

//CHANGE VALUES
let convertedCards = cardsHand;
convertedCards.forEach((element) => {
if (+element.value === 1) element.value = `A`;
if (+element.value === 11) element.value = `J`;
if (+element.value === 12) element.value = `Q`;
if (+element.value === 13) element.value = `K`;
});

return {
convertedCards,
sortedCardsByValue,
};
}

console.log(sortCards(cardsHand).convertedCards);
console.log(sortCards(cardsHand).sortedCardsByValue);

期望输出

sortedCardsByValue

[
{ value: '1', suit: 'C' },
{ value: '10', suit: 'C' },
{ value: '11', suit: 'C' },
{ value: '12', suit: 'C' },
{ value: '13', suit: 'C' }
]

convertedCards

[
{ value: 'A', suit: 'C' },
{ value: '10', suit: 'C' },
{ value: 'J', suit: 'C' },
{ value: 'Q', suit: 'C' },
{ value: 'K', suit: 'C' }
]

问题根源

  1. sort()是原地修改:Array.sort()不会返回新数组,而是直接修改原数组。所以sortedCardsByValue只是原数组的引用,不是独立数组。
  2. 对象引用未隔离:convertedCards = cardsHand只是复制了数组的引用,两个变量指向同一个数组。后续修改convertedCards里的对象属性,会直接影响原数组(也就是sortedCardsByValue指向的数组)里的对象。

修正后的代码

const cardsHand = [
  { value: "1", suit: "C" },
  { value: "13", suit: "C" },
  { value: "12", suit: "C" },
  { value: "11", suit: "C" },
  { value: "10", suit: "C" },
];

function sortCards(cardsHand) {
  // 先对原数组浅拷贝后排序,避免修改原数组,得到独立的排序后原数值数组
  const sortedOriginal = [...cardsHand].sort((a, b) => +a.value - +b.value);
  
  // 基于排序后的数组,创建转换后的新数组,每个对象单独拷贝,避免影响原排序数组的对象
  const convertedCards = sortedOriginal.map(card => {
    let newValue = card.value;
    switch (+newValue) {
      case 1: newValue = 'A'; break;
      case 11: newValue = 'J'; break;
      case 12: newValue = 'Q'; break;
      case 13: newValue = 'K'; break;
    }
    return { ...card, value: newValue };
  });

  return {
    convertedCards,
    sortedCardsByValue: sortedOriginal,
  };
}

const result = sortCards(cardsHand);
console.log(result.sortedCardsByValue);
console.log(result.convertedCards);

修正说明

  • 使用[...cardsHand]创建原数组的浅拷贝,再执行排序,确保sortedOriginal是独立数组,不会影响原输入数组。
  • 用map生成convertedCards时,通过{ ...card }拷贝每个卡牌对象,修改新对象的value属性,不会改动sortedOriginal里的对象。
  • 改用switch替代多个if,逻辑更简洁易读。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 16:05:58