微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么这个 Javascript 对象不会改变?

如何解决为什么这个 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 举报,一经查实,本站将立刻删除。