修改对象属性值时如何不改变原对象?(卡牌数组场景)
卡牌排序与转换后数组内容一致的问题
现有卡牌数组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' } ]
问题根源
sort()是原地修改:Array.sort()不会返回新数组,而是直接修改原数组。所以sortedCardsByValue只是原数组的引用,不是独立数组。- 对象引用未隔离:
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
相关产品推荐
相关产品推荐

