讓json寫入/讀取順序一致的
你提出了一個非常核心且常見的問題!這幾乎是所有 JavaScript 開發者都會遇到的情況。
為什麼順序會亂掉?
物件的本質是「字典」,不是「列表」 :JavaScript 的物件 (Object),在設計上是一個 鍵-值對 (key-value) 的集合 ,就像一本字典。它的主要目的是讓你能夠透過一個「鍵」(例如 'timer1')快速找到對應的「值」(計時器的詳細資料)。它的設計 沒有 保證你放入的順序就是它儲存或讀取的順序。
for...in 迴圈的不可靠性 :你提到的 for() 迴圈,很可能指的是 for...in 迴圈 (for (const key in myObject))。這個迴圈在規範中是 不保證遍歷順序 的。瀏覽器可以根據自己的內部優化(例如,它可能會先把數字鍵名的屬性排在前面)來決定遍歷的順序。
JSON 的規範 :JSON (JavaScript Object Notation) 格式本身也定義物件為「一個無序的鍵/值對集合」。所以當你將一個物件 JSON.stringify() 儲存,再 JSON.parse() 讀取回來時,順序同樣沒有任何保證。
正確的解決方案:使用陣列 (Array)
修改前的資料結構 (你的現狀,有問題的)
// 問題:無法保證順序
let timers = {
'timer1': { time: '01:00', desc: '計時器1', status: 'stopped' },
'timer3': { time: '00:00', desc: '計時器3', status: 'stopped' },
'timer2': { time: '00:00', desc: '計時器2', status: 'stopped' }
};
// 解決方案:使用陣列來儲存物件,順序將被完美保留
let timers = [
{ id: 'timer1', time: '01:00', desc: '計時器1', status: 'stopped' },
{ id: 'timer3', time: '00:00', desc: '計時器3', status: 'stopped' },
{ id: 'timer2', time: '00:00', desc: '計時器2', status: 'stopped' }
];
最外層從 {} (物件) 變成了 [] (陣列)。 每個計時器都是陣列中的一個獨立物件。 我們為每個物件增加了一個 id 屬性,這樣你仍然可以唯一地識別和操作每一個計時器。
如何操作新的資料結構
timers.push(newTimer);
// 現在 timers 陣列的順序就是 [timer1, timer3, timer2, timer4]
function renderTimers() {
// 清空現有的顯示
container.innerHTML = '';
// 按照陣列順序遍歷
for (const timerInfo of timers) {
// 根據 timerInfo 創建 HTML 元素並添加到頁面上
// 這裡的順序將與 timers 陣列的順序完全一致
createTimerElement(timerInfo);
}
}
const idToDelete = 'timer3';
timers = timers.filter(timer => timer.id !== idToDelete);
// 修改 id 為 'timer1' 的計時器的描述
const idToUpdate = 'timer1';
const timerToUpdate = timers.find(timer => timer.id === idToUpdate);
if (timerToUpdate) {
timerToUpdate.desc = "新的描述";
}
總結
將儲存計時器資料的結構從 {} 物件改為 [] 陣列。 在儲存到 chrome.storage 之前,確保它是陣列。 從 chrome.storage 讀取後,使用 for...of 或 forEach 來渲染,這樣順序就永遠不會錯了。
留言
張貼留言