前言:
面試的時候碰到了這么個問題,在這里總結一下。
什么是 Javacript 深度拷貝,既然有深度拷貝,那有沒有淺度拷貝呢?答案是有的。
舉個簡單的例子解釋一下:
淺度拷貝:就好比我們從俄羅斯買了20架蘇27戰斗機,飛機人家是給你了,但是技術并沒轉讓,飛機壞了還得求人家來給你修。
深度拷貝:就好比我們從俄羅斯買了20架蘇27戰斗機,并且轉讓了全部技術,這樣,我們就能自己生產了,技術全挖過來了,俄羅斯管不著了。
第一節 對象的拷貝
1、淺度拷貝
var a = {
name:'aa',
age:'20'
}
b = a;
b; //結果如下
/*
b = {
name:'aa',
age:'20'
}
*/
問:我們將對象 a 作一下修改,b 是否會跟著變?
var a = {
name:'aa',
age:'20'
}
b = a;
// 那么
b = {
name:'aa',
age:'20'
}
a.name = 'cc';
b;
/* b = { name:'cc',age:'20' } */
對象 b 是會跟著對象 a 的變動而變化的,這個我想大家應該都明白。
2、深度拷貝
就是 a 對象的操作不會影響到 b 對象(當然,反過來亦如此)
var a = {
name:'yy',
age:26
};
var b = new Object();
// 注意重點來了
b.name=a.name;
b.age=a.age;
a.name='xx';
console.log(b);
//Object { name="yy", age=26}
console.log(a);
//Object { name="xx", age=26}
哎呦,還真是,對象 a 變了而對象 b 沒發生變化。
總結一下,其實是這樣的。
1.淺度拷貝:基本類型為值傳遞,對象仍為引用傳遞。
2.深度拷貝:所有元素或屬性完全克隆,對于原引用類型完全獨立。
上面這種寫法,對象屬性很少的情況下,是可以使用的,但是多了,就不行了。所以我們還是要寫個函數,將要拷貝的對象的屬性遍歷一遍,賦值給一個新對象。如下,
function deepCopy(source) {
var result = {};
for(var key in source) {
result[key] = typeof source[key] === 'object'? deepCoyp(source[key]): source[key];
}
return result;
}
var a = {
name: '小明',
age: 18
}
b = deepCopy(a);
/* b = { name: '小明',age:18 }*/
同理,說一下數組的淺度拷貝和深度拷貝
第二節 數組的拷貝
1、淺度拷貝
var arr = [1,2,3];
var arr2 = arr;
console.log(arr2); // [1,2,3]
arr[0] = "one";
console.log(arr1); // ["one", 2, 3]
console.log(arr2); // ["one", 2, 3]
與對象的淺度拷貝是一樣的。
2、深度拷貝
方法1:利用 slice 函數
slice() 方法可從已有的數組中返回選定的元素。
arrayObject.slice(start,end) // start 必選 end 可選
說明:
1.請注意,該方法并不會修改數組,而是返回一個子數組。
2.如果 end 未被規定,那么 slice() 方法會選取從 start 到數組結尾的所有元素。
var arr = [1,2,3];
var arr2 = arr.slice(0); // 重點看這里
console.log(arr2); // [1, 2, 3]
arr = ["one","two","three"];
console.log(arr); // ["one","two","three"]
console.log(arr2); // [1, 2, 3]
方法2:利用 concat 函數
concat() 方法用于連接兩個或者多個數組。
arrayObject.concat(arrayX,arrayX,......,arrayX)
說明:
該方法不會改變現有的數組,而僅僅會返回被連接數組的一個副本
var arr = [1,2,3];
var arr2 = arr.concat(); // 重點看這里,concat 一個空數組進去,那結果不變
console.log(arr2); // [1, 2, 3]
arr = ["one","two","three"];
console.log(arr); // ["one","two","three"]
console.log(arr2); // [1, 2, 3]
總結:
說點題外話,做前端也有一段時間了,以前,碰到問題就加個書簽或者建個 word 簡要的記一下。從今年開始認真的在有道云筆記上寫筆記,并且把合適的推送到自己的博客上。個人覺得建立博客的意義除了知識共享以及備忘,更重要的一點是迫使自己去思考和總結,既要寫出來,還要別人能看懂,花費的時間挺多,但是值得。