2015-04-07 43 views
0

我以前遇到过这个问题,并且为了得到我需要的结果而砍掉了它,但是最后我还是碰到了墙,而且我不明白为什么这会一直出现。暂时的Javascript对象

在JavaScript中,如何捕获仅指向原始对象的浅拷贝?这让我疯狂。我知道JS中的所有东西都是一个指针,但是必须有一种方法来获得一个深度拷贝,它在修改时不会更改原始对象。下面是我与工作代码:

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); 
    } 
} 

的对象,MyGame.tetromino,正在更新到任何MyGame.ai_object.piece是,当我真正想要做的是改变我创建了临时变量和使用MyGame.tetromino重置我的临时对象。我哪里错了?

回答

2

在它的简单,并假设一切都没有不安全的扩展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行李)有一个在underscore.js

编辑_.clone - 一个深拷贝,简单而又重复的就足够了,再假设未Object.prototype也不Array.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; 
} 

注意:如果传递一个包含循环引用的结构体,该函数将无法完成。

+0

所以,如果我理解正确,我会调用这个函数,它会返回给我一个对象的浅拷贝。 – sparkyShorts

+1

@sparkyShorts,是的。 'var copy = Object.shallowCopy(original)' – Alnitak

+0

所以我实现了它,就像你所建议的那样,但我仍然没有得到浅拷贝。我看到并理解你的代码是如何工作的,但我不明白它是如何创建浅拷贝的。你能详细说明一下吗? – sparkyShorts

0

意识到,我曾问一个浅拷贝,但确实需要一个副本后(让他们向后出于某种原因,没有足够的咖啡因我猜),我发现这对interwebs和其他几个答案:

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

这创建了我一直在寻找的深拷贝。在我意识到自己的错误后,我发现了其他几个答案。

编辑:

使用JSON.parse(JSON.stringify(OBJ))使用了大量的资源。这是一个获得深层副本的替代方法:

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

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