JS:创建了新状态对象;防止“流行音乐”影响旧对象

时间:2019-08-11 11:57:43

标签: javascript javascript-objects

在下面的游戏代码中:即使使用了javascript new关键字创建了一个新对象来保存下一个状态对象,应用于下一个状态对象的方法仍然引用了下一个状态对象制作下一个状态对象时,会将“裸”属性传递给构造函数。

在将变换用作属性作为下一个对象构造函数的参数之前,将其应用于属性时,保留第一状态属性很容易(例如,使用timeOfDay可以轻松避免覆盖第一状态)。

我已经采取了一种“地图”解决方法,以避免在修改黑手党列表时引用第一状态对象,但这可能不是最干净或最容易理解的。

其他一些先前回答的问题建议使用类似Object.assign({},this.mafia)的名称,但这不允许在下面的代码中使用“ pop方法”。

请提出一种避免覆盖第一状态对象的方法,如下所示。

class mafiaVillageState{

    constructor(timeOfDay, villagers, mafia){
        this.timeOfDay = timeOfDay;
        this.villagers = villagers;
        this.mafia = mafia;
    }    

    killPlayer(){
        let gameStep = new mafiaVillageState(1-this.timeOfDay,
            this.villagers.map(v => {return v}),

            // this.mafia
            this.mafia.map(v => {return v})      
            // Object.assign({},this.mafia)

        );
        if (this.timeOfDay == 1){
            gameStep.mafia.pop();
        } else {
            gameStep.villagers.pop();
        }
        return gameStep 
    }
}

let first = new mafiaVillageState(
    1,
    ["Sana","Dahyun"], //the villagers
    ["Chaeyoung","Tzuyu"] //the mafia
)

“玩游戏”是通过获取下一个游戏状态来完成的:

let next = first.killPlayer();

console.log(first.timeOfDay);
console.log(first.mafia);
console.log(next.timeOfDay);
console.log(next.mafia);
  • 没有任何变通方法来避免引用第一个对象的输出会修改第一个状态(我不希望覆盖初始状态,因此不希望这样做,以便在选择要杀死的玩家时更加复杂,这有助于调试)
1
Array(1) ["Chaeyoung"]
0
Array(1) ["Chaeyoung"]
  • 带有“映射解决方法”的输出:这是所需的输出;一个黑手党被杀,第一状态不变
1
Array(2) ["Chaeyoung", "Tzuyu"]
0
Array(1) ["Chaeyoung"]

-使用Object.assign({},this.mafia)会导致以下错误

' TypeError: gameStep.mafia.pop is not a function '

1 个答案:

答案 0 :(得分:2)

如果出于调试原因要保留旧对象,则需要为新状态创建一个新对象,无法解决。我认为使用.map并不是一个糟糕的解决方案,但是如果您正在寻找更清洁的方法,则可以使用es6数组扩展运算符或Array.prototype.splice

killPlayer(){
    let gameStep = new mafiaVillageState(
        1 - this.timeOfDay,
        [...this.villagers], // alternatively: this.villagers.splice(),
        [...this.mafia],
    );

    ...
}

spread运算符将要散布的数组中的项目转储到新数组中(您也可以执行[... arr1,... arr2]之类的操作来组合数组)。您应该注意,这些项目不会被复制,因此,如果您在任一阵列中进行某些突变,则该突变都会影响包含该对象的所有状态。