JavaScript对象引用Bug求助:循环处理Filmstrip时上传数组异常
Let's break down what's happening here and how to fix it:
The Root Cause
In your forEach loop, when you do needUploadPages.push(filmstrip), you're pushing a reference to the original filmstrip object from Win.dataSource.filmstrips. Since objects in JavaScript are passed by reference, any subsequent changes to filmstrip (like updating filmstrip.content in later iterations) will directly modify the objects already stored in needUploadPages. That's why your upload data ends up inconsistent—all entries in the array point to the same underlying objects that get overwritten as the loop runs.
The Solution: Create a Copy of the Object
To avoid this, you need to push a copy of the filmstrip object into needUploadPages instead of the original reference. The type of copy you need depends on whether Filmstrip has nested objects:
Shallow Copy (for flat
Filmstripstructures)
Use object spread syntax orObject.assign()to create a shallow copy. This works ifFilmstripdoesn't have nested objects (like arrays or other objects) in its properties:needUploadPages.push({ ...filmstrip });or
needUploadPages.push(Object.assign({}, filmstrip));Deep Copy (for nested
Filmstripstructures)
IfFilmstriphas nested objects, a shallow copy won't work—you'll still have references to the nested data. UsestructuredClone()(built into modern browsers and Node.js) to create a full deep copy:needUploadPages.push(structuredClone(filmstrip));Note: Avoid using
JSON.parse(JSON.stringify())if yourFilmstripobject contains functions, dates, or other non-serializable values, as this method will lose or corrupt that data.
Modified Code Example
Here's how your updated loop would look using a shallow copy (adjust to deep copy if your Filmstrip has nested properties):
let needUploadFiles: string[] = [], needUploadPages: Filmstrip[] =[], needUploadContents: string[] = []; Win.dataSource.filmstrips.forEach((filmstrip: Filmstrip, index) => { if (Page.pages[index]) { filmstrip.content = Page.pages[index].cleanHTML(); } let hash = Lib.sha1(filmstrip.content), content: string = filmstrip.content; if (filmstrip.hash != hash) { needUploadFiles.push(hash); // Push a copy instead of the original reference needUploadPages.push({ ...filmstrip }); needUploadContents.push(content); } }); // Promise.uploa...
This way, each entry in needUploadPages is a separate object that won't be affected by changes to the original filmstrip in later loop iterations.
内容的提问来源于stack exchange,提问作者zhaoxuan du

