要理解 JavaScript中淺拷貝和深拷貝的區別,首先要明白JavaScript的數據類型javascript
JavaScript有兩種數據類型,基礎數據類型和引用數據類型前端
基礎數據類型:保存在棧內存中的簡單數據段 ,有undefined,boolean,number,string,nulljava
引用數據類型:Array,對象,Function 保存在堆內存空間中網站
a1 = 0;a2 = 'this is str';a3 = null 存放在棧內存中this
var c =[1,2,3] 與 var d = {m:20} 變量名與內存地址存儲在棧內存中,[1,2,3]與{m:20} 做爲對象存儲在堆內存中prototype
基礎數據類型的複製(如var a = 20 var b = a)3d
引用數據類型的複製 ( var m ={a:10, b:20} var n = m)指針
m與n指向同一個內存空間,當m或者n改變時,另外一個也跟着改變code
如m.a = 80 ; console.log(n.a) // 80對象
怎麼樣使引用數據類型有各自獨立的內存空間
1、採用遞歸的方法複製拷貝對象
function deepclone(obj) { let objClone = Array.isArray(obj) ? [] : {}; if (obj && typeof obj === "object") { for (key in obj) { //if (obj.hasOwnProperty(key)) { //也能夠不加 if (obj[key] && typeof obj[key] === "object") { objClone[key] = deepclone(obj[key]) } else { objClone[key] = obj[key] } //} } } return objClone } var a = [1, 2, 3, 4]; var b = deepclone(a); a[0] = 8 console.log(a, b);
Array.isArray(obj):ECMAScript 5.1 (ECMA-262) 考慮到的兼容性,能夠用下面的方法實現較好的兼容
if (!Array.isArray) {
Array.isArray = function(arg) {
return Object.prototype.toString.call(arg) === '[object Array]';
};
}
2、用JSON.stringify把對象轉成字符串,再用JSON.parse把字符串轉成新的對象。
function deepclone(obj){ var _obj = JSON.stringify(obj); var cloneObj = JSON.parse(_obj); return cloneObj } var a =[1,2,3,4]; var b= deepclone(a); a[0]=8 console.log(a,b); //能夠用JSON.stringify與JSON.parse實現深拷貝的緣由是JSON.stringify(obj)轉換成字符串,變成基本數據類型,基本類型拷貝是直接在棧內存新開空間,直接複製一份名-值,不影響以前的對象
總結:
**淺拷貝(shallow copy):只複製指向某個對象的指針,而不復制對象自己,新舊對象共享一塊內存; **
深拷貝(deep copy):複製並建立一個一摸同樣的對象,不共享內存,修改新對象,舊對象保持不變;實現深拷貝主要有2種方法
(1)遞歸
(2)JSON.stringify結合JSON.parse
公衆號:前端之攻略