當咱們利用v-bind:來綁定屬性向子組件傳遞對象的時候,有時候咱們須要子組件改變的時候不改變父組件的值,通常能夠利用JSON.stringify(JSON.parse(jsonstr))將傳遞來的對象賦值到子組件本身的data,這樣作的原理是對傳過來的值從新賦予一個空間,從而解決雙向綁定。,可是es6有一個深度賦值的方法也能夠解決這個問題, let obj= Object.assign({}, obj)也能夠解決。es6
好比一個數組(array)淺度拷貝是當數組a變量成數組b的時候,b改變裏面的數組數值的時候,a也隨着改變.json
深度拷貝是噹噹數組a變量成數組b的時候,b改變裏面的數組數值的時候,a裏面的數組數組不隨着改變,數組
var arr = ["a", "b", "c", "d", "e"];
var Arr = JSON.stringify(arr); //先轉化爲string字符串的類型
var Brr = JSON.parse(Arr); //在解析字符串的類型
Brr[1] = 'h'; //這樣修改Brr中的數組的時候就不會影響到arr裏面數組的值
console.log('arr:' + arr); //結果是arr:a,b,c,d,e
console.log("Arr:" + Brr); //結果是Arr:a,b,c,d,e
複製代碼
那麼爲何淺度拷貝會改變a的數組值而深度拷貝則不會呢?函數
由於淺度拷貝指向的是同一個內存,而深度拷貝是增長了一個新的內存,因此不會影響到原來a的內存, 所 以就不會改變原來的值 eg.
測試
var arr = ["a", "b", "c", "d", "e"];
var Arr = arr;
Arr[1] = 'h';
console.log('arr:' + arr); //arr的下標1的‘b’也變成了‘h’ 結果是:arr:a,h,c,d,e
console.log("Arr:" + Arr); //結果是:Arr:a,h,c,d,e
複製代碼
對於數組的深拷貝常規的有三種方法:ui
方法一:遍歷複製spa
var arr = ["a", "b"], arrCopy = [];
for (var item in arr) arrCopy[item] = arr[item];
arrCopy[1] = "c";
arr // => ["a", "b"]
arrCopy // => ["a", "c"]
複製代碼
考慮僞多維數組能夠寫成函數形式:雙向綁定
function arrDeepCopy(source){
var sourceCopy = [];
for (var item in source) sourceCopy[item] = typeof source[item] === 'object' ? arrDeepCopy(source[item]) : source[item];
return sourceCopy;
}
複製代碼
這種方法簡單粗暴,可是利用JS自己的函數咱們能夠更加便捷地實現這個操做。code
方法二:slice()對象
能夠參考 W3School 對 slice() 方法的描述:slice() 方法可從已有的數組中返回選定的元素。
調用格式爲:
arrayObject.slice(start,end)
方法返回一個新的數組,包含從 start 到 end (不包括該元素)的 arrayObject 中的元素。該方法並不會修改數組,而是返回一個子數組。
在這裏咱們的思路是直接從數組開頭截到尾:
arrCopy = arr.slice(0); arrCopy[1] = "c"; arr // => ["a", "b"] arrCopy // => ["a", "c"] 能夠看出成功建立了一份原數組的拷貝。
方法三:concat()
能夠參考 W3School 對 concat()
方法的描述:concat()
方法用於鏈接兩個或多個數組。
調用格式爲: arrayObject.concat(arrayX,arrayX,......,arrayX)
該方法不會改變現有的數組,而僅僅會返回被鏈接數組的一個副本。
使用這種方法的思路是咱們用原數組去拼接一個空內容,放回的即是這個數組的拷貝:
arrCopy = arr.concat();
arrCopy[1] = "c";
arr // => ["a", "b"]
arrCopy // => ["a", "c"]
複製代碼
對於數組的深拷貝咱們有了概念,那麼通常對象呢?
咱們給出一個對象:
var obj = { "a": 1, "b": 2 };
複製代碼
一樣作測試:
var objCopy = obj;
objCopy.b = 3;
obj // => { "a": 1, "b": 3 }
objCopy // => { "a": 1, "b": 3 }
複製代碼
一樣,簡單的賦值運算只是建立了一份淺拷貝。
而對於對象的深拷貝,沒有內置方法可使用,咱們能夠本身命名一個函數進行這一操做:
var objDeepCopy = function(source){
var sourceCopy = {};
for (var item in source) sourceCopy[item] = source[item];
return sourceCopy;
}
複製代碼
可是對於複雜結構的對象咱們發現這個函數並不適用,例如:
var obj = { "a": { "a1": ["a11", "a12"], "a2": 1 }, "b": 2 };
複製代碼
因此須要進行一點修改:
var objDeepCopy = function(source){
var sourceCopy = {};
for (var item in source) sourceCopy[item] = typeof source[item] === 'object' ? objDeepCopy(source[item]) : source[item];
return sourceCopy;
}
var objCopy = objDeepCopy(obj);
objCopy.a.a1[1] = "a13";
obj // => { "a": { "a1": ["a11", "a12"], "a2": 1 }, "b": 2 }
objCopy // => { "a": { "a1": ["a11", "a13"], "a2": 1 }, "b": 2 }
複製代碼
三、對象數組的深拷貝
若是再考慮更奇葩更復雜的狀況,例如咱們定義:
var obj = [{ "a": { "a1": ["a11", "a12"], "a2": 1 }, "b": 2 }, ["c", { "d": 4, "e": 5 }]]; 這是一個由對象、數組雜合成的奇葩數組,雖然咱們平時寫程序基本不可能這麼折騰本身,可是能夠做爲一種特殊狀況來考慮,這樣咱們就能夠結合以前說的方法去拓展拷貝函數:
var objDeepCopy = function (source) {
var sourceCopy = source instanceof Array ? [] : {};
for (var item in source) {
sourceCopy[item] = typeof source[item] === 'object' ? objDeepCopy(source[item]) : source[item];
}
return sourceCopy;
}
var objCopy = objDeepCopy(obj);
objCopy[0].a.a1[1] = "a13";
objCopy[1][1].e = "6";
obj // => [{ "a": { "a1": ["a11", "a12"], "a2": 1 }, "b": 2 }, ["c", { "d": 4, "e": 5 }]]
objCopy // => [{ "a": { "a1": ["a11", "a13"], "a2": 1 }, "b": 2 }, ["c", { "d": 4, "e": 6 }]]
複製代碼