簡單的描述了淺拷貝和深拷貝的區別後,分別進行實現且所有方法都已進行試驗。 ...
實現淺拷貝和深拷貝
1. 淺拷貝和深拷貝的區別
簡單點說,淺拷貝拷貝完後,修改拷貝的內容可能會對源內容產生影響。而深拷貝就是拷貝前後的內容相互不影響。
那為什麼拷貝前後的內容會相互影響呢?那就得知道原始數據類型和引用類型的區別了。
在記憶體中的存儲方式不同,原始數據類型在記憶體中是堆存儲,引用類型是棧存儲 棧(stack)為自動分配的記憶體空間,它由系統自動釋放;而堆(heap)則是動態分配的記憶體,大小不定也不會自動釋放。在記憶體中存儲方式的不同導致了原始數據類型不可變 原始數據類型和引用數據類型做賦值操作一個是傳值一個是傳址
- 原始數據類型:自然不用說了,它的值就是一個數字,一個字元或一個布爾值。
- 引用類型:是一個對象類型,值是什麼呢?它的值是指向記憶體空間的引用,就是地址,所指向的記憶體中保存著變數所表示的一個值或一組值。
而在js中,有三大引用類型即Object、Array、Function。
因此在拷貝他們的時候,應該使用深拷貝來避免於源內容產生影響。
2.實現淺拷貝
2.1 object.assign()
Object.assign()
方法用於將所有可枚舉屬性的值從一個或多個源對象複製到目標對象。它將返回目標對象。
var arr = [1, [7, [9]], {a:'1'}, function(){}, null, undefined, NaN];
var result= Object.assign(arr); arr[2][a]='222';
console.log(arr); //output: [1, [7, [9]], {a:'222'} , function(){}, null, undefined, NaN]; console.log(result); //output: [1, [7, [9]], {a:'222'} , function(){}, null, undefined, NaN];
2.2 拓展運算符…
var arr = [1, [7, [9]], {a:'1'}, function(){}, null, undefined, NaN]; var result= [...arr]; arr[2][a]='222'; console.log(arr); //output: [1, [7, [9]], {a:'222'} , function(){}, null, undefined, NaN]; console.log(result); //output: [1, [7, [9]], {a:'222'} , function(){}, null, undefined, NaN];
以上兩種方法很簡單,一句話就搞定啦。
3.實現深拷貝
3.1 JSON
var arr = [1, [7, [9]], {a:'1'}, function(){}, null, undefined, NaN];
var result = JSON.parse(JSON.stringify(arr));
arr[2][a]='222';
console.log(arr); //output: [1, [7, [9]], {a:'222'} , function(){}, null, undefined, NaN];
console.log(result); //output: [1, [7,[9]], {a:'111'}, null, null, null, null]
所以可以看出,使用JSON不能實現對function、undefined、NaN的拷貝。
如果拷貝的數據不存在function、undefined、NaN這些數據類型的話,使用JSON是個很簡便的方法呢。
3.2 遞歸遍歷
想要對所有類型都能夠實現深拷貝的話,那就只能自己封裝個函數來實現啦。
var arr = [1, [7, [9]], { a: '1'}, function () {}, null, undefined, NaN]; function deepCopy(arr) { if (typeof obj !== 'object') return; var newObj = obj instanceof Array ? [] : {}; for (var key in obj) { if (obj.hasOwnProperty(key)) { if(obj[key]===null){newObj[key]=null;continue;} newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key]; } } return newObj; } var result = deepCopy(arr)); arr[2][a]='222';
console.log(arr); //output: [1, [7, [9]], {a:'222'} , function(){}, null, undefined, NaN]; console.log(result); //output: [1, [7, [9]], { a: '1'}, function () {}, null, undefined, NaN]