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

如何不按引用传递将tiles对象推入moves数组?

How to Save Independent State of 'tiles' in 'moves' Array Without Reference Issues

Yep, you hit the nail on the head—this is all about JavaScript's reference-based handling of objects and arrays. Every time you push self.tiles into self.moves, you're just adding a pointer to the same underlying array and its objects. So when you update tiles later, all those pointers in moves point to the now-changed data.

To fix this, you need to create a deep copy of tiles every time you push it to moves. A shallow copy (like using slice() or [...self.tiles]) won't cut it here because that only copies the array itself, not the objects inside it—those would still be references.

Here are a few solid solutions tailored to your code:

Solution 1: JSON Serialization (Quick & Simple)

This works great if your tiles array only contains plain objects, numbers, strings, booleans, or other JSON-serializable data (which is almost always the case for game board state).

Modify your startGame and makeMove functions like this:

this.startGame = function () {
    // other code
    // Create a deep copy of tiles
    const tilesSnapshot = JSON.parse(JSON.stringify(self.tiles));
    self.moves.push(tilesSnapshot);
};

this.makeMove = function () {
    // other code
    const tilesSnapshot = JSON.parse(JSON.stringify(self.tiles));
    self.moves.push(tilesSnapshot);
};

The JSON.stringify converts your tiles data into a string, and JSON.parse turns it back into a brand new object/array—no shared references left.

Solution 2: Custom Deep Copy Function (For Complex Data)

If your tiles includes non-JSON data (like functions, Date objects, or Symbols), you'll need a recursive deep copy function to handle those cases:

// Add this helper function somewhere in your code
function deepClone(obj) {
    // Return primitive values as-is
    if (obj === null || typeof obj !== 'object') return obj;
    
    // Handle arrays
    if (Array.isArray(obj)) {
        return obj.map(item => deepClone(item));
    }
    
    // Handle plain objects
    const clonedObj = {};
    for (const key in obj) {
        if (obj.hasOwnProperty(key)) {
            clonedObj[key] = deepClone(obj[key]);
        }
    }
    return clonedObj;
}

Then use it in your methods:

this.startGame = function () {
    // other code
    const tilesSnapshot = deepClone(self.tiles);
    self.moves.push(tilesSnapshot);
};

this.makeMove = function () {
    // other code
    const tilesSnapshot = deepClone(self.tiles);
    self.moves.push(tilesSnapshot);
};

Solution 3: Native structuredClone() (Modern Environments)

If you're targeting modern browsers or Node.js 17+, the built-in structuredClone() API is perfect—it handles most data types (including Date, Map, Set, and even circular references) without extra code:

this.startGame = function () {
    // other code
    const tilesSnapshot = structuredClone(self.tiles);
    self.moves.push(tilesSnapshot);
};

this.makeMove = function () {
    // other code
    const tilesSnapshot = structuredClone(self.tiles);
    self.moves.push(tilesSnapshot);
};

Whichever method you pick, each entry in self.moves will now be an independent snapshot of your board state at that moment—no more overwriting old entries when you update tiles.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 03:49:04