gpt4 book ai didi

javascript - 对象已创建,但似乎正在共享引用

转载 作者:行者123 更新时间:2023-12-03 06:13:47 25 4
gpt4 key购买 nike

我正在构建一个编辑器,在编辑器中,当您按下播放键时,它会将一堆对象转换为 Prefab (这向我的引擎解释了如何构建对象)。当我停止它们时,我想再次重建预制件,它应该回到原来的状态(在按下播放之前)。我遇到的问题是,当按下 stop 时,项目不会返回到原始状态。它们似乎保持在按下停止键时的状态。

这是我用来来回转换预制件的类:

class Prefab {

public name: string;
public components: PrefabComponent[] = [];

public static create(gameObject: GameObject): Prefab {
let prefab = new Prefab;
prefab.name = gameObject.name;
gameObject.components.forEach(comp => {
let prefabComp = new PrefabComponent;
prefabComp.name = comp.name;
for (let c in comp) {
let prefabProp = new PrefabProperty;
prefabProp.name = c;
if (typeof comp[c] == 'object') {
prefabProp.value = Object.create(comp[c]);
} else {
prefabProp.value = comp[c];
}
prefabComp.properties.push(prefabProp);
}
prefab.components.push(prefabComp);
});
return prefab;
}

public static toObject(prefab: Prefab): GameObject {
let gameObject = new GameObject(prefab.name);
prefab.components.forEach(comp => {
let newComp;
if (comp.name.toLowerCase() != 'transform') {
newComp = gameObject.addComponent(comp.name);
}
if (!newComp) {
newComp = gameObject.getComponent(comp.name);
}
comp.properties.forEach(prop => {
if (prop.value instanceof Sprite) {
newComp[prop.name] = Sprite.create(prop.value.path);
} else if (typeof prop.value == 'object') {
newComp[prop.name] = Object.create(prop.value);
} else {
newComp[prop.name] = prop.value;
}
});
});
return gameObject;
}

}

class PrefabComponent {

public name: string;
public properties: PrefabProperty[] = [];

}

class PrefabProperty {

public name: string;
public value: any;

}

这是我开始和停止游戏的方式:

play.addEventListener('click', (event) => {
event.preventDefault();
// Game has started
// Stop was pressed
if (game instanceof SpyNginMain) {
game.stopGame();
game = null;
play.classList.remove('active');
pause.classList.remove('active');
// Reset the editor
EditorObjectManager.clear();
prefabs.forEach(prefab => {
EditorObjectManager.addItem(Prefab.toObject(prefab));
});
updateScene();
}
// Game has not started
// Play was pressed
else {
game = new SpyNginMain();
prefabs = [];
EditorObjectManager.items.forEach(item => {
prefabs.push(Prefab.create(item));
});
game.init(scene, prefabs);
game.startGame();
play.classList.add('active');
}
});

问题似乎是当我尝试使用 PrefabProperty 类转换对象时。我认为它不是创建实例,而是创建对原始实例的引用,但我不确定......

最佳答案

由于以下代码,您的 create 方法肯定会保留对原始对象的引用:

    if (typeof comp[c] == 'object') {
prefabProp.value = Object.create(comp[c]);
} else {
prefabProp.value = comp[c];
}

Object.create 调用会创建一个以原始对象为原型(prototype)的新对象,因此,如果您随后在原始对象中添加/修改/删除属性,所做的更改也会出现在新创建的对象。

我认为您在这里的意思是克隆原始对象?有许多现有的克隆实现(例如 lodash 的 cloneDeep )。

我会将上面引用的所有五行替换​​为单个 clone(comp[c]) 调用,因为您的 typeof 检查在其他方面也不可靠(例如typeof null == 'object' 为 true,typeof [1,2,3] == 'object' 为 true,等等)。

关于javascript - 对象已创建,但似乎正在共享引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39197745/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com