javascript:.filter 更新原始数组中的对象?

0 javascript arrays for-loop object filter

我正在为学校创建一个小游戏,我正在创建一个由 100 个图块组成的棋盘,它们是 JS 对象。其中一些图块被随机阻挡(这是它们的属性之一)。玩家不能进去。

我还需要在这些图块上随机放置 4 个武器。

所以我创建了一系列未被阻挡的图块,然后我将我的武器一个接一个地放在这些空闲图块上。为了确保其中一个图块上还没有武器,我使用 .filter() 创建一个新的未阻塞且空的图块数组(没有武器)。

问题是,当我更新新数组中的图块属性时(由 .filter 发出,以确保同一位置不会有两个武器),它会更新父数组中图块的属性,我不明白这一点。我读过 .filter() 方法不会更新父数组,但在这里它会更新?也许是因为它是一个 JS 对象?

感谢您的澄清!

let tilesUnblocked = []
//here function creating tiles and pushing unblocked tiles in the array above
for (i = 0; i < weapons.length; i++) {
    let tilesUnblockedAndEmpty = tilesUnblocked.filter(tile => tile.weapon === false) 
    let randomInt = Math.round(tilesUnblockedAndEmpty.length * Math.random())
    let weaponElt = weapons[i].HTMLElement
    weaponElt.css({ //some css })
    tilesUnblockedAndEmpty[randomInt].HTMLElement.append(weaponElt)
    tilesUnblockedAndEmpty[randomInt].weapon = true //updating array created from filter
    tilesUnblockedAndEmpty[randomInt].weaponType = weapons[i].name //updating array created from filter
}
console.log(tilesUnblocked) //I will find in this array the objects updated at the end of the foor loop, on the array issued of .filter method !
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 5

\n

也许是因为它是 JS 对象?

\n
\n\n

是的。如果你有这个:

\n\n
const original = [\n    {example: 42},\n    {example: 21}\n];\n
Run Code Online (Sandbox Code Playgroud)\n\n

你的记忆里有这样的东西:

\n\n
\n +\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\ x92\xe2\x88\x92+\原始\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92>| (数组) |\n +\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\ xe2\x88\x92\xe2\x88\x92+ +\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2 \x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92+\n | 0 |\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92 \xe2\x88\x92>| (对象)|\n | 1 |\xe2\x88\x92\xe2\x88\x92+ +\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\ x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92+\n +\xe2\x88 \x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92+ | | 示例:42 |\n | +\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\ xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92+\n | +\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\ xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92+\n +\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92 \xe2\x88\x92\xe2\x88\x92\xe2\x88\x92>| (对象) |\n +\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\ xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92+\n | 例如: 21 |\n +\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\ xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92+\n
\n\n

如果您随后这样做:

\n\n
const filtered = original.filter(entry => entry.example !== 42);\n
Run Code Online (Sandbox Code Playgroud)\n\n

你有:

\n\n
\n +\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\ x92\xe2\x88\x92+\原始\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92>| (数组) |\n +\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\ xe2\x88\x92\xe2\x88\x92+ +\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2 \x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92+\n | 0 |\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92 \xe2\x88\x92>| (对象)|\n | 1 |\xe2\x88\x92\xe2\x88\x92+ +\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\ x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92+\n +\xe2\x88 \x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92+ | | 示例:42 |\n | +\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\ xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92+\n | +\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\ xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92+\n +\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92 \xe2\x88\x92\xe2\x88\x92\xe2\x88\x92>| (对象)|\n | +\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\ xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92+\n | | 示例:21 |\n | +\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\ xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92+\n +\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92 \xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92+ |\n过滤\xe2\x88\x92\xe2\x88\ x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92>| (数组)| |\n +\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88 \x92\xe2\x88\x92+ |\n | 0 |\xe2\x88\x92\xe2\x88\x92+\n +\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\ x88\x92\xe2\x88\x92\xe2\x88\x92\xe2\x88\x92+\n
\n\n

正如你所看到的,两个数组都指向同一个对象。如果更改该对象的状态(例如,通过添加或更改属性),则该更改通过两个数组都可见。

\n\n

如果您希望过滤后的数组有副本,则必须明确执行此操作:

\n\n
const filtered = original\n    .filter(entry => entry.example !== 42)\n    .map(entry => ({...entry});\n
Run Code Online (Sandbox Code Playgroud)\n\n

这只是复制对象的一种方法,这个问题的答案中还涵盖了其他几种方法。

\n