如何解决为什么这个 Javascript 对象不会改变?
我有一个名为 Scene 的对象,它存储屏幕尺寸以及一个 Shape 对象数组,每个对象都有一个 x 和 y 坐标。我想打乱一个 Scene 对象并获得一个 scrambledScene 对象,以便我可以将 scrambledScene 与原始对象进行比较。这是我想出的函数:
function scrambleScene(scene) {
var scrambledScene = {...scene};
for(var i = 0; i < scene.shapes.length; i++) {
scrambledScene.shapes[i].x = getRandInt(0,scene.width);
scrambledScene.shapes[i].y = getRandInt(0,scene.height);
}
return(scrambledScene);
}
问题是当这个函数运行时,它返回一个与传递给它的 Scene 对象相同的对象。什么都没有改变。以下是我使用的函数的定义。我对 OOP 很陌生,所以请随时提供指针(与 JS 不同,为什么 var clone = object 只返回一个指针而不是另一个对象?!!?!?!!)。
function getRandInt(min,max) {
return(Math.floor(Math.random() * (max - min + 1)) + 1);
}
function Shape(shapeX,shapeY,shapeSize,shapeType) {
this.x = shapeX;
this.y = shapeY;
this.size = shapeSize;
this.type = shapeType;
//circle uses arc() function,which takes the center of the circle as a reference
//circle sets the radius to this.size
//square uses rect() function,which take the upper left corner as a reference
//square sets the height and width of the square to this.size
if(this.type !== 'circle' && this.type !== 'square') {
console.error('Invalid shapeType: ',this.shapeType);
}
this.centerX = function() {
if(this.type === 'square') {
return(this.size/2 - this.x);
}
if(this.type === 'circle') {
return(this.x);
}
}
this.centerY = function() {
if(this.type === 'square') {
return(this.size/2 - this.y);
}
if(this.type === 'circle') {
return(this.y);
}
}
this.isInside = function(point_x,point_y) {
if(this.type === 'square') {
//canvas y increases as you go down
//if point_x is greater than x + size,then its far too right
//if point_x is less than x,then its far too left
//if point_y is greater than y + size,then its below
//if point_y is less than y,then its above
//if none of these are true then its inside
if(point_x <= x + size && point_x >= x && point_y <= y + size && point_y >= y) return(true);
}
if(this.type === 'circle') {
//checks distance from point to center of the circle
//if its greater than the radius of the circle then its outside
//if its less than or equal to the radius then its inside
const distance = Math.sqrt(Math.pow(point_x - x,2) - Math.pow(point_y - y,2));
if(this.distance >= size) return(true);
}
}
}
function Scene(numberOfShapes,sceneWidth,sceneHeight) {
this.shapes = [];
for(var i = 0; i < numberOfShapes; i++) {
var shapeType = Math.random() < 0.5 ? 'square' : 'circle';
this.shapes[i] = new Shape(getRandInt(0,sceneWidth),getRandInt(0,sceneHeight),100,shapeType)
}
this.width = sceneWidth;
this.height = sceneHeight;
}
解决方法
所以对象被改变了,只是那个对象的克隆也被改变成完全相同。
在 scrambleScene 函数中,我试图创建所谓的 Scene 对象的浅克隆。我真正需要的是一个深度克隆。浅层克隆就像您在 Windows 上复制了一个包含文件的文件夹,但不是实际复制其中的文件,而是将文件替换为这些文件的快捷方式。如果您编辑原始文件并打开快捷方式,您将看到编辑,因为它只是一个快捷方式,而不是一个新文件。深度克隆类似于复制包含所有文件的文件夹。如果您编辑原始文件,则不会更改其副本,因为它们是两个不同的文件。
如果你继续类比,当我运行 scrambleScene 函数时,它编辑了原始文件,当我查看形状时,它是相同的,因为它只是一个快捷方式,而不是一个新文件。我需要复制文件,而不是创建快捷方式。
您可以使用 JSON 创建一个完全独立的对象。有一些 limitations,但就我而言,它有效。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。