2011-11-21 98 views
30

如何在JavaScript中克隆/複製地圖?克隆/複製Javascript地圖變量

我知道如何克隆一個數組,但是如何克隆/複製一張地圖?

var myArray = new Array(1, 2, 3); 
var copy = myArray.slice(); 
// now I can change myArray[0] = 5; & it wont affect copy array 

// Can I just do the same for map? 
var myMap = new ?? // in javascript is it called a map? 
var myMap = {"1": 1, "2", 2}; 
var copy = myMap.slice(); 
+0

在JavaScript中,地圖被稱爲對象。 – slebetman

+0

有這麼多重複的這個問題,我甚至不知道從哪裏開始! – Stefano

+7

在2015年的JavaScript中,有一個真正的Map對象。 –

回答

10

一個簡單的方法是將源地圖的每個屬性複製到目標地圖:

var newMap = {}; 
for (var i in myMap) 
newMap[i] = myMap[i]; 
+2

這只是一個淺拷貝...如果myMap [i]本身就是一張地圖呢? – Stefano

+0

Stefano,你可以做到這一點,如果你想(檢查是否是一個typeof對象,然後執行它的屬性的副本...可能是通過遞歸相同的函數),但請記住,現在你必須關心它們作爲祖先元素的可能性,這會使你陷入無限循環。如果你真的想要一個深層的副本,你可能想看看這樣做的圖書館。 – rob

+1

我知道,但我認爲你應該先在你的答案中寫下這一點;-) – Stefano

2

沒有內置的克隆/複製。您可以將自己的方法寫入淺拷貝或深拷貝:

function shallowCopy(obj) { 
    var result = {}; 
    for (var i in obj) { 
     result[i] = obj[i]; 
    } 
    return result; 
} 

function deepCopy(obj) { 
    var result = {}; 
    for (var i in obj) { 
     // recursion here, though you'll need some non-trivial logic 
     // to avoid getting into an endless loop. 
    } 
    return result; 
} 

Javascript中的所有對象都是動態的,並且可以分配新的屬性。你引用它的「地圖」實際上只是一個空的對象。一個數組是也是的一個對象,使用方法如slice和屬性如length

+0

不明白你寫的2個函數有什麼不同之處! –

+0

@HananAYousef區別未實現;在深層複製中,您必須遞歸(爲每個子節點調用deepCopy),但由於子節點可能包含對父節點的引用(例如,window.window2 = window),因此無法深入複製這些引用而無法進入無限循環。 – Nicole

2

沒有什麼內置

要麼使用一個行之有效的遞歸特性複印機或者性能ISN是一個問題,串行化爲JSON並再次解析爲新對象。

6

JQuery有一個方法來擴展一個對象(合併兩個對象),但是這個方法也可以用來通過提供一個空對象來克隆一個對象。

// Shallow copy 
var newObject = jQuery.extend({}, oldObject); 

// Deep copy 
var newObject = jQuery.extend(true, {}, oldObject); 

更多信息可在jQuery documentation中找到。這裏

var newMap = new Map(existingMap) 

文檔:

111

在JavaScript中引入地圖這是很簡單的考慮構造函數接受一個可迭代https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map

+9

這是今天正確的答案。 –

+0

上面的小問題:像這樣克隆地圖,會調用Map.prototype.entries和Map.prototype.set。這意味着:如果您編寫擴展Map的類並覆蓋這兩種方法中的任何一種,那麼如果擴展方法依賴super所不具備的屬性,那麼只需編寫'new ExtendedMap(extendedMapObj)'就不會起作用。 –

+2

另一個需要注意的是,如果映射值是引用類型(如數組),看起來好像不是遞歸深度複製的,而是淺拷貝的。 – ossek

1

我注意到,地圖應該需要特殊的處理,因此與所有建議此線程的代碼將爲:

function deepClone(obj) { 
    if(!obj || true == obj) //this also handles boolean as true and false 
     return obj; 
    var objType = typeof(obj); 
    if("number" == objType || "string" == objType) // add your immutables here 
     return obj; 
    var result = Array.isArray(obj) ? [] : !obj.constructor ? {} : new obj.constructor(); 
    if(obj instanceof Map) 
     for(var key of obj.keys()) 
      result.set(key, deepClone(obj.get(key))); 
    for(var key in obj) 
     if(obj.hasOwnProperty(key)) 
      result[key] = deepClone(obj[ key ]); 
    return result; 
} 
0

克隆地圖非常簡單,因爲您所談論的是強制一個物體。有一個在ES6一個Map,你應該看看,但複製的對象,只要使用Object.assign()

let map = {"a": 1, "b": 2} 
let copy = Object.assign({}, map); 

您還可以使用cloneDeep()從Lodash

let copy = cloneDeep(map);