1 回答

TA貢獻2037條經(jīng)驗 獲得超6個贊
淺拷貝
僅對object頂層鍵進行遍歷和重新賦值(給對應(yīng)的引用),例如:
var a = {
x: {
name: 'x',
value: 10,
},
y: 10,
o: {},
}
var b = {
x: {
name: 'x2',
value: 20,
},
y: {
name: 'y2',
value: 20,
},
z: {}
}
$.extend(a, b)
這個過程里面,從b中取出所有頂層元素,即b.x, b.y, b.z,然后將它們一一賦值給a對應(yīng)的鍵,所以最后a就有了新的a.x, a.y, a.z,同時,a.o還保留在a中,這時a.x === b.x, a.y === b.y, a.z === b.z,因為它們都是指向同一個對象的引用。既然是引用,當(dāng)你操作a.x的時候,比如a.x.name = 'x3',那么b.x.name也就變成了'x3'。
深拷貝
深拷貝將深入對象元素的末層進行重新賦值,而非引用。就拿上面的a,b舉例,執(zhí)行:
$.extend(true, a, b)
將會深入b內(nèi)部進行遍歷,拿每一個節(jié)點的值與a對應(yīng)(一模一樣)的節(jié)點進行比較,如果不同則為a開辟存儲空間,把值賦進去,如果a不存在這個節(jié)點,就為它創(chuàng)建后賦值進去。a的第一層子節(jié)點跟b第一層不存在相等關(guān)系,連==都不成立。
深拷貝后,a原有的一些節(jié)點會保留下來,b給過去的節(jié)點會覆蓋或增加,但是和b之間不存在任何引用關(guān)系,所以修改a的任何一個節(jié)點,都不會影響b。這在一些數(shù)據(jù)處理的時候非常有用,為了不影響原始數(shù)據(jù),需要在處理數(shù)據(jù)之前深拷貝一份再進行處理。
深拷貝的時候,數(shù)組的索引號被當(dāng)做鍵名對待,所以數(shù)組元素會被修改,而不是被添加到原始數(shù)據(jù)中。比如:
var a = [ { x: 1, }, { x: 2, },]var b = [ { y: 2 },]$.extend(true, a, b)
將會得到:
var a = [ { x: 1, y: 2 }, { x: 2, },]
b的第一個原始被合并到a的第一個元素里面去了,這個合并是因為數(shù)組按照元素的索引號作為鍵來進行操作。所以,合并數(shù)組不能用extend,而應(yīng)該考慮用merge或concat。
添加回答
舉報