當前位置:編程學習大全網 - 源碼下載 - 什麽是js深拷貝和淺拷貝及其實現方式

什麽是js深拷貝和淺拷貝及其實現方式

今天來給大家說壹下JS的js深拷貝和淺拷貝,它們有什麽區別,有什麽作用呢?下面給大家舉例說明壹下。

var m = { a: 10, b: 20 }var n = m;n.a = 15;// 這時m.a的值是多少

m.a會輸出15,因為這是淺拷貝,n和m指向的是同壹個堆,對象復制只是復制的對象的引用。

深拷貝

深拷貝和上面淺拷貝不同,就是徹底copy壹個對象,而不是copy對象的引用,例如,還是之前的例子,我們這麽寫:

var m = { a: 10, b: 20 }var n = {a:m.a,b:m.b};n.a = 15;

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

深拷貝和淺拷貝

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

淺拷貝只復制指向某個對象的指針,而不復制對象本身,新舊對象還是***享同壹塊內存。但深拷貝會另外創造壹個壹模壹樣的對象,新對象跟原對象不***享內存,修改新對象不會改到原對象。

淺拷貝的實現方式

1、可以通過簡單的賦值實現

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

function simpleClone(initalObj) {

var obj = {};

for ( var i in initalObj) {

obj[i] = initalObj[i];

}

return obj;

}

var obj = {

a: "hello",

b:{

a: "world",

b: 21

},

c:["Bob", "Tom", "Jenny"],

d:function() {

alert("hello world");

}

}

var cloneObj = simpleClone(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() { alert("changed"); };

console.log(obj.b);

console.log(obj.c);

console.log(obj.d);2、Object.assign()實現

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

var obj = { a: {a: "hello", b: 21} };var initalObj = Object.assign({}, obj);initalObj.a.a = "changed";console.log(obj.a.a); // "changed"

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

var obj1 = { a: 10, b: 20, c: 30 };var obj2 = Object.assign({}, obj1);obj2.b = 100;console.log(obj1);// { a: 10, b: 20, c: 30 } <-- _被改到console.log(obj2);// { a: 10, b: 100, c: 30 }深拷貝的實現方式

1、方法壹還是手動復制

和上面的舉例壹樣,手動復制可以實現深拷貝。

2、對象只有壹層的話可以使用上面的:Object.assign()函數

3、轉成 JSON 再轉回來

var obj1 = { body: { a: 10 } };var obj2 = JSON.parse(JSON.stringify(obj1));obj2.body.a = 20;console.log(obj1);// { body: { a: 10 } } <-- _被改到console.log(obj2);// { body: { a: 20 } }console.log(obj1 === obj2);// falseconsole.log(obj1.body === obj2.body);// false用JSON.stringify把對象轉成字符串,再用JSON.parse把字符串轉成新的對象。

可以封裝如下函數

var cloneObj = function(obj){

var str, newobj = obj.constructor === Array ? [] : {};

if(typeof obj !== 'object'){

return;

} else if(window.JSON){

str = JSON.stringify(obj), //系列化對象

newobj = JSON.parse(str); //還原

} else {

for(var i in obj){

newobj[i] = typeof obj[i] === 'object' ?

cloneObj(obj[i]) : obj[i];

}

}

return newobj;};4、遞歸拷貝

function deepClone(initalObj, finalObj) {

var obj = finalObj || {};

for (var i in initalObj) {

var prop = initalObj[i]; // 避免相互引用對象導致死循環,如initalObj.a = initalObj的情況

if(prop === obj) {

continue;

}

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

obj[i] = (prop.constructor === Array) ? [] : {};

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

} else {

obj[i] = prop;

}

}

return obj;}var str = {};var obj = { a: {a: "hello", b: 21} };deepClone(obj, str);console.log(str.a);5、使用Object.create()方法

直接使用var newObj = Object.create(oldObj),可以達到深拷貝的效果。

function deepClone(initalObj, finalObj) {

var obj = finalObj || {};

for (var i in initalObj) {

var prop = initalObj[i]; // 避免相互引用對象導致死循環,如initalObj.a = initalObj的情況

if(prop === obj) {

continue;

}

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

obj[i] = (prop.constructor === Array) ? [] : Object.create(prop);

} else {

obj[i] = prop;

}

}

return obj;}6、jquery

jquery 有提供壹個$.extend可以用來做 Deep Copy。

var $ = require('jquery');var obj1 = {

a: 1,

b: { f: { g: 1 } },

c: [1, 2, 3]};var obj2 = $.extend(true, {}, obj1);console.log(obj1.b.f === obj2.b.f);// false7、lodash

另外壹個很熱門的函數庫lodash,也有提供_.cloneDeep用來做 Deep Copy。

var _ = require('lodash');var obj1 = {

a: 1,

b: { f: { g: 1 } },

c: [1, 2, 3]};var obj2 = _.cloneDeep(obj1);console.log(obj1.b.f === obj2.b.f);// false這個性能還不錯,使用起來也很簡單。

相信看了這些案例妳已經掌握了方法,更多精彩請關註Gxl網其它相關文章!

相關閱讀:

HTML裏的最後壹行文字顯示不全怎麽處理

怎樣用css3做出圖標效果

CSS的編碼怎麽轉換

  • 上一篇:c語言中的月歷制作
  • 下一篇:windowsserver2019桌面體驗版區別
  • copyright 2024編程學習大全網