[英]Object array's object properties changing when returning array
我有一個功能可以操縱和創建對象數組,並向數組中的每個項目添加position
鍵,但是它似乎根本無法正常工作...
我的功能:
var fillQueue = function(choices, currentQueue) {
var choice, i, positionInQueue, previousTitle, resultQueue;
resultQueue = [];
previousTitle = "";
i = 0;
while (i < 10) {
positionInQueue = i + 1;
console.log('Adding song to position ' + positionInQueue);
if (currentQueue[i]) {
previousTitle = currentQueue[i].title;
currentQueue[i].position = positionInQueue;
resultQueue.push(currentQueue[i]);
} else {
choice = choices[Math.floor(Math.random() * choices.length)];
if (choice.title !== previousTitle) {
previousTitle = choice.title;
choice.position = positionInQueue;
resultQueue.push(choice);
} else {
choice = choices[Math.floor(Math.random() * choices.length)];
previousTitle = choice.title;
choice.position = positionInQueue;
resultQueue.push(choice);
}
}
i++;
}
return resultQueue;
};
如果正確調用此函數,將值替換為choices
和currentQueue
( currentQueue
也可以是空數組),如下所示,該函數將返回一個預期的數組,但是由於某種原因,需要擰緊其中每個對象的position
鍵。
var test = fillQueue([ {title: '1'}, {title: '2'}, {title: '3'}, {title: '4'} ], [ { title: '5', position: 1 } ]);
上面的變量將包含以下內容:
[ { title: '5', position: 1 },
{ title: '1', position: 9 },
{ title: '3', position: 7 },
{ title: '1', position: 9 },
{ title: '2', position: 10 },
{ title: '2', position: 10 },
{ title: '3', position: 7 },
{ title: '1', position: 9 },
{ title: '1', position: 9 },
{ title: '2', position: 10 } ]
如您所見,它沒有將position
正確地添加到每個對象中。 返回數組中的每個對象都應具有i + 1
的position
,但似乎是從1到10的某個隨機數-某些對象甚至具有相同的position
。
我努力了:
position
重命名為其他名稱,以防它已被JavaScript使用 position
被添加到對象之前和之后.push
將其投入的陣列。 這讓我真的很困惑。 您的幫助將不勝感激。
您正在將引用推入數組,因此每次更新choice.position時 ,對數組中同一選項的所有引用都會獲得相同的位置值。
要解決此問題,請復制選擇對象,更新其位置並將其推入數組,例如
if (choice.title !== previousTitle) {
previousTitle = choice.title;
newChoice = objCopyShallow(choice); // see below for copy function
newChoice.position = positionInQueue;
resultQueue.push(newChoice);
}
對於此應用程序,一個簡單的復制功能是:
function objCopyShallow(obj) {
return Object.keys(obj).reduce(function(acc, v) {
acc[v] = obj[v];
return acc;
},{});
}
如果您想要更深入的了解,這里有關於“如何復制對象”的一百萬個問題和答案。
就像RobG已經說過的那樣,您正在推送對數組的引用。因此創建您選擇對象的副本,然后推送到您的數組。 使用clone()
創建對象的副本,將您的分配更改為choice = clone(choices[Math.floor(Math.random() * choices.length)]);
你完成了。
function clone(obj) {
if (null == obj || "object" != typeof obj) return obj;
var copy = obj.constructor();
for (var attr in obj) {
if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
}
return copy;
}
我能夠提出以下建議。 這可以避免在JS中使用引用為“陷阱”的for / while循環,因此在使用它更新值時需要注意這一點。
var fillQueue = function(choices, currentQueue) { // concat choices to end of currentQueue // create a new array instance with updated position property using .map // keep 10 elements from new array starting at index 0 return currentQueue.concat(choices).map( (e, i) => { return Object.assign({title:e.title, position:i+1}); }).splice(0, 10) };
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.