2015-04-07 46 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)。