临时Javascript对象

Temp Javascript Objects

本文关键字:对象 Javascript 临时      更新时间:2023-09-26

我以前遇到过这个问题,为了得到我需要的结果,我一直在努力,但最终还是遇到了困难,不明白为什么这种情况会一直发生。

在JavaScript中,如何只捕获不指向原始对象的浅副本

MyGame.runAllPossibleMoves = function() {
MyGame.ai_object.board = MyGame.tetrominos;
MyGame.ai_object.piece = MyGame.tetromino;
  for(var i = 0; i < 10; i++){
    if(i < MyGame.ai_object.piece.pivot.x){
      while(moveLeft() && i < MyGame.ai_object.piece.pivot.x){
       //do piece movement
      }
      hardDrop();
    }
    console.log(MyGame.ai_object.piece.pivot.x + ',' + MyGame.ai_object.piece.pivot.y);
    console.log(MyGame.tetromino.pivot.x + ',' + MyGame.tetromino.pivot.y);
    MyGame.ai_object.board = MyGame.tetrominos;
    MyGame.ai_object.piece = MyGame.tetromino;
    //console.log(MyGame.ai_object.piece);
  }
}

当我真正想做的是修改我创建的temp变量并使用MyGame.tetromino重置我的临时对象时,对象MyGame.tetromino被更新为MyGame.ai_object.piece。我哪里错了?

在最简单的情况下,假设没有任何东西具有不安全的扩展Object.prototype:

Object.shallowCopy = function(obj) {
    var r = Array.isArray(obj) ? new Array(obj.length) : {};
    for (var k in obj) {
        r[k] = obj[k];
    }
    return r;
}

由于这是一个浅层副本,任何"复制"的值本身就是一个对象,都将保留对原始值的引用。

等效函数存在于各种库中。特别是(没有与jQuery关联的DOM行李)undercore.js 中有_.clone

EDIT-对于深度复制,简单的递归应该足够了,再次假设Object.prototypeArray.prototype都没有被不安全地修改:

Object.deepCopy = function(obj) {
    var r = obj;
    if (typeof obj === 'object') {
        r = Array.isArray(obj) ? new Array(obj.length) : {};
        for (var k in obj) {
            r[k] = Object.deepCopy(obj[k]);
        }
    }
    return r;
}

注意:如果传递了一个包含对自身循环引用的结构,则此函数将无法完成。

在意识到我要求一个浅拷贝,但确实需要一个拷贝(由于某种原因,我想是咖啡因不够)后,我在网络间和其他几个答案中发现了这一点:

MyGame.ai_object.board = (JSON.parse(JSON.stringify(MyGame.tetrominos)));
MyGame.ai_object.piece = (JSON.parse(JSON.stringify(MyGame.tetromino)));

这创造了我想要的深度复制。在意识到自己的错误后,我在SO上找到了其他几个答案。

编辑:

使用JSON.parse(JSON.stringfy(obj))会消耗大量资源。这里有一种获得深度复制的替代方法:

deepCopy = function(obj){
  var temp;
  for(var n in obj){
    temp[n] = obj[n];
  }
  return temp;
}

这将复制obj中的每个项,并将其分配给新对象temp。这不会创建obj中任何对象的深度副本(您必须再次调用deepCopy)。