談談淺拷貝和深拷貝的區別,以及實現的方法
兩者的區別:一個物件淺複製後,是深層次的物件地址的複製,並沒有開闢新的棧,也就是複製的結果是兩個物件指向同一個地址,修改其中一個物件的屬性,則另一個物件的屬性也會發生改變,而深複製的則是開闢了一個新的棧,兩個物件對應兩個不同的地址,修改一個物件的屬性,不會改變另一個物件的屬性。
話不多說,上程式碼:
// 原始物件
var obj = {
a:1,
arr: [2,3],
say:function(){
console.log('hello')
},
obj1:{
arr:[34,55,5],
hand:function(){
console.log('hand')
},
obj3:{
a:1,
take:function(){
console.log('take')
}
}
}
};
// 開始淺複製
var shallowObj = shallowCopy(obj);
// 定義淺複製邏輯
function shallowCopy(src) {
var dst = {};
for (var prop in src) {
if (src.hasOwnProperty(prop)) {
dst[prop] = src[prop];
}
}
return dst;
}
// 改變複製後的新物件屬性值(第一層屬性)
shallowObj.a = 2;
shallowObj.arr = [9,8];
shallowObj.say = function(){
console.log('world')
}
// 列印新物件的及方法
console.dir(shallowObj)
shallowObj.say(); // world
// 列印原物件及方法
console.dir(obj);
obj.say(); // hello
結果如圖所示:
結論 : 修改新物件的屬性值,第一層的屬性值的確沒有變化,重點來了,我們給第二層以及更深層次的屬性複製試試
// 原始物件
var obj = {
a:1,
arr: [2,3],
say:function(){
console.log('hello')
},
obj1:{
arr:[34,55,5],
hand:function(){
console.log('hand')
},
obj3:{
a:1,
take:function(){
console.log('take')
}
}
}
};
// 開始淺複製
var shallowObj = shallowCopy(obj);
// 定義淺複製邏輯
function shallowCopy(src) {
var dst = {};
for (var prop in src) {
if (src.hasOwnProperty(prop)) {
dst[prop] = src[prop];
}
}
return dst;
}
// 改變複製後的新物件的屬性值(第二層以及更深層次)
shallowObj.obj1.obj3.take = function(){
console.log('shallowObj_take')
}
shallowObj.obj1.hand = function(){
console.log('shallowObj_hand')
}
// 列印新物件的方法呼叫
shallowObj.obj1.obj3.take(); // shallowObj_take
shallowObj.obj1.hand(); // shallowObj_hand
// 列印原物件的方法呼叫
obj.obj1.obj3.take(); // shallowObj_take
obj.obj1.hand(); // shallowObj_hand
問題出現了:原物件的方法被新物件的修改,而產生變化。
原因是複製的是物件的地址指標,兩個屬性共同指向一個物件,只要其一發生變化,另一個也隨之變化
深拷貝的方法:
1.可以遞迴遞迴去複製所有層級屬性
// 原始物件
var obj = {
a:1,
arr: [2,3],
say:function(){
console.log('hello')
},
obj1:{
arr:[34,55,5],
hand:function(){
console.log('hand')
},
obj3:{
a:1,
take:function(){
console.log('take')
}
}
}
};
// 深複製邏輯(遞迴呼叫)
function deepClone(obj){
let objClone = Array.isArray(obj)?[]:{};
if(obj && typeof obj==="object"){
for(key in obj){
if(obj.hasOwnProperty(key)){
//判斷obj子元素是否為物件,如果是,遞迴複製
if(obj[key] && typeof obj[key] ==="object"){
objClone[key] = deepClone(obj[key]);
}else{
//如果不是,簡單複製
objClone[key] = obj[key];
}
}
}
}
return objClone;
}
// 開始深複製
var shallowObj = deepClone(obj);
// 改變複製後的新物件的屬性值(第二層以及更深層次)
shallowObj.obj1.obj3.take = function(){
console.log('shallowObj_take')
}
shallowObj.obj1.hand = function(){
console.log('shallowObj_hand')
}
shallowObj.obj1.obj3.take(); // shallowObj_take
shallowObj.obj1.hand(); // shallowObj_hand
obj.obj1.obj3.take(); // take
obj.obj1.hand(); // hand
結論:深拷貝後改變物件的屬性值,不會影響原始物件的值。
2.除了遞迴,我們還可以借用JSON物件的parse和stringify
function deepClone(obj){
let _obj = JSON.stringify(obj),
objClone = JSON.parse(_obj);
return objClone
}
let a=[0,1,[2,3],4],
b=deepClone(a);
a[0]=1;
a[2][0]=1;
console.log(a,b);
3.除了上面兩種方法之外,我們還可以借用JQ的extend方法
$.extend( [deep ], target, object1 [, objectN ] )
deep表示是否深拷貝,為true為深拷貝,為false,則為淺拷貝
target Object型別 目標物件,其他物件的成員屬性將被附加到該物件上。
object1 objectN可選。 Object型別 第一個以及第N個被合併的物件。
let a=[0,1,[2,3],4],
b=$.extend(true,[],a);
a[0]=1;
a[2][0]=1;
console.log(a,b);
相關推薦
談談淺拷貝和深拷貝的區別,以及實現的方法
兩者的區別:一個物件淺複製後,是深層次的物件地址的複製,並沒有開闢新的棧,也就是複製的結果是兩個物件指向同一個地址,修改其中一個物件的屬性,則另一個物件的屬性也會發生改變,而深複製的則是開闢了一個新的棧
【js】深拷貝和淺拷貝區別,以及實現深拷貝的方式
一、區別:簡單點來說,就是假設B複製了A,當修改A時,看B是否會發生變化,如果B也跟著變了,說明這是淺拷貝,如果B沒變,那就是深拷貝。 此篇文章中也會簡單闡述到棧堆,基本資料型別與引用資料型別,因為這些概念能更好的讓你理解深拷貝與淺拷貝。 例如: let a=[0,1,2,3,4], b=
python的複製,淺拷貝和深拷貝的區別
在python中,物件賦值實際上是物件的引用。當建立一個物件,然後把它賦給另一個變數的時候,python並沒有拷貝這個物件,而只是拷貝了這個物件的引用 一般有三種方法, alist=[1,2,3,["a","b"]] (1)直接賦值,傳遞物件的引用而已,原始列表改變,被
引用賦值,淺拷貝和深拷貝
lan art csdn 理解 article 淺拷貝和深拷貝 blank .net hang 三種引用: http://blog.csdn.net/XIAXIA__/article/details/41652057 深拷貝和淺拷貝的理解: http://blog.csdn
python賦值,淺拷貝和深拷貝
>>> a = 1 >>> b = a >>> a = 2 >>> a 2 >>> b 1 >>> 你將 1 賦給 a 變數,然後拷貝 a 中的值,將它賦給變數 b。當稍 後將
JavaScript中淺拷貝和深拷貝,棧堆詳解
版權宣告:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/weixin_40983119/article/details/82995151 簡單來說,JavaScript中單個等於號的賦值就是拷貝,但是呢這個這個賦值可以分為兩種,一種是賦的是資料,一種是賦
java淺拷貝和深拷貝的區別
淺拷貝是指:只複製一個物件,物件內部存在的指向其他物件陣列或者引用則不復制。 深拷貝是指:不僅複製當前的物件,如果物件中還存在引用,則將引用的物件一起復制。 java中使用到的clone方法是淺拷貝,下面是簡單演示: 首先定義一個簡單類A,申明一個屬性aa = 1;
淺拷貝和深拷貝的區別.md
淺拷貝和深拷貝的區別: 淺拷貝 對一個已知物件進行拷貝,編譯系統會自動呼叫一種建構函式——拷貝建構函式,如果使用者未定義拷貝建構函式,則會呼叫預設拷貝建構函式,呼叫一次建構函式,呼叫兩次解構函式,兩個物件的指標成員所指記憶體相同,但是程式結束時該記憶體卻被釋放了
賦值、淺拷貝和深拷貝的區別?
首先要知道變數,物件,引用三者之間的關係 變數: 是一個元素, 擁有指向物件的連線空間 **物件:**被分配的一塊記憶體,儲存代表的值 引用: 是變數到物件的指標 一、賦值 在 Python 中,物件的賦值就是簡單的物件引用, 如下所示: a = [1,2,
淺拷貝和深拷貝的區別和實現方法
對於這個問題可以從深拷貝和淺拷貝的使用或起源說起。 1. js變數包含兩種不同資料型別的值基本型別和引用型別 基本型別包括ES6新增的一共是6種,具體如下 string ,number, null ,undefined, boolean ,symbol 引用型
【進階4-1期】詳細解析賦值、淺拷貝和深拷貝的區別
一、賦值(Copy) 賦值是將某一數值或物件賦給某個變數的過程,分為下面 2 部分 基本資料型別:賦值,賦值之後兩個變數互不影響 引用資料型別:賦址,兩個變數具有相同的引用,指向同一個物件,相互之間有影響 對基本型別進行賦值操作,兩個變數互不影響。 // 木易楊 let a = "muy
淺拷貝和深拷貝(談談java中的clone)
clone顧名思義就是複製, 在Java語言中, clone方法被物件呼叫,所以會複製物件。所謂的複製物件,首先要分配一個和源物件同樣大小的空間,在這個空間中建立一個新的物件。那麼在java語言中,有幾種方式可以建立物件呢? 1. 使用new操作
JavaScript中淺拷貝和深拷貝的區別和實現
JavaScript有兩種資料型別,基礎資料型別和引用資料型別。基礎資料型別都是按值訪問的,我們可以直接操作儲存在變數中的實際的值。而引用型別如Array,我們不能直接操作物件的堆記憶體空間。引用型別的值都是按引用訪問的,即儲存在變數物件中的一個地址,該地址
淺拷貝和深拷貝的區別?
//student.cpp #include "student.h" #include <iostream> #include <string.h> using namespace std; Student::Student() { name = new char(20
引用型別的賦值、淺拷貝和深拷貝的區別
ICloneable 介面:支援克隆,即用與現有例項相同的值建立類的新例項。 MemberwiseClone 方法:建立當前 System.Object 的淺表副本。 淺拷貝:給物件拷貝一份新的物件。 淺拷貝的定義 —— 只對值型別(或string)型別分配新的記憶
淺談賦值、淺拷貝和深拷貝的區別
一:賦值 在Python中,物件的賦值就是簡單的物件引用,這點和C++不同,如下所示: a = [1,2,'hello',['python','C++']] b = a 在上述情況下,a和b是一樣的,它們指向同一片記憶體,b不過是a的別名,是引用。我們
python中的淺拷貝和深拷貝
div blog deep imp class pri cnblogs 字符串 style 1.淺拷貝 copy.copy() 淺拷貝是拷貝只拷貝最外一層(這裏所說的拷貝是重新生成一個內存地址,也就是只有最外層的地址是重新生成) import copy li=[23,45
【轉】python的淺拷貝和深拷貝
end ont code append pen ron 實例 賦值 深拷貝 直接賦值:其實就是對象的引用(別名)。 淺拷貝(copy):拷貝父對象,不會拷貝對象的內部的子對象。 深拷貝(deepcopy): copy 模塊的 deepcopy 方法,完全拷貝了父對象及其
js 對象的淺拷貝和深拷貝
tex bject script cnblogs ons assign 對象 而已 obj //淺拷貝,拷貝內存塊,拷貝部門代碼不共存 var obj = { a : "a", b : "b", c : { text : "這是一個文本" } }
java淺拷貝和深拷貝
一起 head 有著 cloneabl 獨立 head對象 影響 如果 覆蓋 轉:http://blog.csdn.net/u014727260/article/details/55003402 實現clone的2點: 1,clone方法是Object類的一個方法