js深拷貝和淺拷貝

2021-09-14 02:50:29 字數 3537 閱讀 8501

走在前端的大道上

var m = 

var n = m;

n.a = 15;

// 這時m.a的值是多少

m.a會輸出15,因為這是淺拷貝,n和m指向的是同乙個堆,物件複製只是複製的物件的引用。

深拷貝和上面淺拷貝不同,就是徹底copy乙個物件,而不是copy物件的引用,例如,還是之前的例子,我們這麼寫:

var m = 

var n = ;

n.a = 15;

這次,我們再來輸出m.a ,發現m.a的值還是10,並沒有改變,m物件和n物件是雖然所有的值都是一樣的,但是在堆裡面,對應的不是同乙個了,這個就是深拷貝。

深拷貝和淺拷貝的示意圖大致如下:

淺拷貝只複製指向某個物件的指標,而不複製物件本身,新舊物件還是共享同一塊記憶體。但深拷貝會另外創造乙個一模一樣的物件,新物件跟原物件不共享記憶體,修改新物件不會改到原物件。

類似上面的例子,當然,我們也可以封裝乙個簡單的函式,如下:

function ******clone(initalobj) ;    

for ( var i in initalobj)

return obj;

}var obj = ,

c:["bob", "tom", "jenny"],

d:function()

}var cloneobj = ******clone(obj);

console.log(cloneobj.b);

console.log(cloneobj.c);

console.log(cloneobj.d);

cloneobj.b.a = "changed";

cloneobj.c = [1, 2, 3];

cloneobj.d = function() ;

console.log(obj.b);

console.log(obj.c);

console.log(obj.d);

object.assign() 方法可以把任意多個的源物件自身的可列舉屬性拷貝給目標物件,然後返回目標物件。但是 object.assign() 進行的是淺拷貝,拷貝的是物件的屬性的引用,而不是物件本身。

var obj =  ,c: 33};

var initalobj = object.assign({}, obj);

initalobj.a.a = "changed";

console.log(obj.a.a); // "changed"

initalobj.c = 66;

console.log(obj.c); // 33

注意:當object只有一層的時候,是深拷貝,例如如下:

var obj1 = ;

var obj2 = object.assign({}, obj1);

obj2.b = 100;

console.log(obj1);

//

console.log(obj2);

//

1、方法一還是手動複製

和上面的舉例一樣,手動複製可以實現深拷貝。

2、物件只有一層的話可以使用上面的:object.assign()函式

3、轉成 json 再轉回來

var obj1 =  };

var obj2 = json.parse(json.stringify(obj1));

obj2.body.a = 20;

console.log(obj1);

// }

console.log(obj2);

// }

console.log(obj1 === obj2);

// false

console.log(obj1.body === obj2.body);

// false

用json.stringify把物件轉成字串,再用json.parse把字串轉成新的物件。

可以封裝如下函式

var cloneobj = function(obj);

if(typeof obj !== 'object') else if(window.json) else

}return newobj;

};

4、遞迴拷貝

function deepclone(initalobj, finalobj) ;    

for (var i in initalobj)

if (typeof prop === 'object') ;

arguments.callee(prop, obj[i]);

} else

}

return obj;

}var str = {};

var obj = };

deepclone(obj, str);

console.log(str.a);

5、使用object.create()方法

直接使用var newobj = object.create(oldobj),可以達到深拷貝的效果。

function deepclone(initalobj, finalobj) ;    

for (var i in initalobj)

if (typeof prop === 'object') else

}

return obj;

}

6、jquery

jquery 有提供乙個$.extend可以用來做 deep copy。

var $ = require('jquery');

var obj1 = },

c: [1, 2, 3]

};var obj2 = $.extend(true, {}, obj1);

console.log(obj1.b.f === obj2.b.f);

// false

7、lodash

另外乙個很熱門的函式庫lodash,也有提供_.clonedeep用來做 deep copy。

var _ = require('lodash');

var obj1 = },

c: [1, 2, 3]

};var obj2 = _.clonedeep(obj1);

console.log(obj1.b.f === obj2.b.f);

// false

這個效能還不錯,使用起來也很簡單。

JS深拷貝和淺拷貝

js中物件分為基本型別和復合 引用 型別,基本型別存放在棧記憶體,復合 引用 型別存放在堆記憶體中 堆記憶體中用於存放由new建立的物件,棧記憶體存放一些基本型別的變數和物件的引用變數 對於簡單變數,記憶體小,直接複製不會發生引用 var a 123 var b a a 123456 console...

JS淺拷貝和深拷貝

1.淺拷貝 copy var obj1 物件存放於堆記憶體中,物件中的鍵值對,值可以為物件,可以為陣列.var obj2 obj1 物件,陣列之間只有引用賦值 obj2.name 撒哈哈 當改動物件obj2的時候,obj1的key對應的value也會更改這是淺拷貝 深拷貝 var obj1 var ...

js淺拷貝和深拷貝

只複製物件的引用位址,兩個物件指向同乙個記憶體位址,所以修改其中任意乙個的值,另乙個也會隨之改變,這就是淺拷貝。1.賦值 var m var n m n.a 15 console.log m.a 15m.a會輸出15,因為這是淺拷貝,n和m指向的是同乙個堆,物件複製只是複製的物件的引用。2.遍歷物件...