JavaScript 的深拷貝和淺拷貝

2021-08-03 05:59:18 字數 3239 閱讀 5058

關於淺拷貝,按照常理理解,以及參考其他語言,我認為淺拷貝指的是和目標物件(陣列)和原始物件(陣列)指向同一塊記憶體空間。賦值操作就是這種淺拷貝。

var src = ;

var target = src;

target.y = 4;

console.log(src.y) //4,相互影響

使用object()建立物件的副本也是一樣的

var person = ;

var newperson = object(person);

newperson.name = 'latency';

console.log(person.name); //"latency"

console.log(person === newperson) //true

但是查了一下 jquery 中 $.extend()方法的實現,發現如果不傳入引數 true 指定深拷貝,那麼$.extend()只複製了一層物件的屬性。object.assign()方法實現的也是這種淺拷貝。

jquery 中的 $.extend():(

jquery.extend = jquery.fn.extend = function() ,

i = 1,

length = arguments.length,

deep = false;

// handle a deep copy situation

if ( typeof target === "boolean" ) ;

i++;

} // handle case when target is a string or something (possible in deep copy)

if ( typeof target !== "object" && !jquery.isfunction( target ) ) ;

} // extend jquery itself if only one argument is passed

if ( i === length )

for ( ; i < length; i++ )

// recurse if we're merging plain objects or arrays

if ( deep && copy && ( jquery.isplainobject( copy ) ||

( copyisarray = array.isarray( copy ) ) ) ) else ;

}// never move original objects, clone them

target[ name ] = jquery.extend( deep, clone, copy );

// don't bring in undefined values

} else if ( copy !== undefined )

}} }

// return the modified object

return target;

};

可以測試一下:
var src = , z: [4, 5, 6]};

var target = $.extend({}, src);

target.x = 7;

target.y.a = 8;

target.z[1] = 9;

console.log(src); //, z: [4, 9, 6]};

可以看到,對於值為基本型別的x屬性,src和target互相不影響,而它們的y和z屬性,還是指向的同一塊記憶體(實際上就是遍歷了最外層的屬性,把每個屬性賦值給目標物件)

。$.extend() 是基於物件的,如果是陣列,slice(0)和 concat() 其實也只複製了一層(

類似$.extend(false, {}, src)

var sarray = [1, [2, 3], ]

var tarray = sarray.slice(0);

tarray[0] = 6;

tarray[1][1] = 7;

tarray[2].y = 8;

console.log(sarray); //[1, [2, 7], ]

var sarray = [1, [2, 3], ]

var tarray = sarray.concat();

tarray[0] = 6;

tarray[1][1] = 7;

tarray[2].y = 8;

console.log(sarray); //[1, [2, 7], ]

深拷貝就沒什麼有爭議的了,目標物件(陣列)重新分配了一塊記憶體區域,其每個屬性(下標)的值和原始物件(陣列)相同。

對於物件的深拷貝,可以使用

$.extend()方法實現:

var src = , z: [4, 5, 6]};

var target = $.extend(true, {}, src);

target.x = 7;

target.y.a = 8;

target.z[1] = 9;

console.log(src); //, z: [4, 5, 6]}

也可以先轉化成

json物件,再轉換為js物件。

var src = , z: [4, 5, 6]};

var target = json.parse(json.stringify(src));

target.x = 7;

target.y.a = 8;

target.z[1] = 9;

console.log(src); //, z: [4, 5, 6]}

對於陣列的深拷貝,最簡單的方法還是使用json序列化

var sarray = [1, [2, 3], ]

var tarray = json.parse(json.stringify(sarray));

tarray[0] = 6;

tarray[1][1] = 7;

tarray[2].y = 8;

console.log(sarray); [1, [2, 3], ]

javascript 淺拷貝和深拷貝

簡單的賦值就是淺拷貝。因為物件和陣列在賦值的時候都是引用傳遞。賦值的時候只是傳遞乙個指標。看下面的例項 var a 1,2,3 var b a var test var c test console.log a console.log b console.log test console.log b...

JavaScript深拷貝和淺拷貝

我們在專案開發過程中經常會拿到乙個資料後需要拷貝乙份副本出來進行操作,而且會發現在很多前端框架中都是拷貝乙份操作的,那麼這就涉及到了 js 中對資料的深淺拷貝問題,所謂深淺拷貝,淺拷貝的意思就是,你只是複製了物件資料的引用,並沒有把記憶體裡的值另外複製乙份,那麼深拷貝就是把值完整地複製乙份新的值。那...

JavaScript篇 深拷貝和淺拷貝

一 概念 1 淺拷貝 拷貝的物件和原來的物件指向同乙個引用位址。乙個改變另乙個也會改變。2 深拷貝 拷貝的物件內容和原來的物件一樣,但是兩個物件指向不同的位址。乙個改變另乙個不會改變。1 淺拷貝 方法一 直接賦值,淺拷貝任意層次 let a let b a console.log a1 a cons...