好記性不如爛筆頭。記在腦子裡不如做點筆記。
什麼是深淺拷貝?
在理解這個問題之前,我們要先去了解一下js的資料型別,js資料型別分為基本資料型別和引用資料型別。
我們知道了js的資料型別,現在就可以來了解什麼是深淺拷貝,先看基本資料型別的拷貝,**如下:基本資料型別:
string,number,null,undefined,boolean
引用資料型別:
object物件(array,function,date,reg)
由上可以看出,a的值改變之後,b的值並沒有跟著改變,再來看看引用型別的拷貝,**如下:var a =2;
// 定義a變數賦值為2
var b = a;
// 把a變數賦值給b
a =1
;// 修改a的值
console.
log(a, b)
;// 1, 2
結果:var a =[1
,2,3
,4];
var b = a;a[1
]=0;
console.
log(a, b)
;

操作和基本資料型別一樣,b會跟著a改變,為什麼會出現這樣的情況呢?因為基本資料型別儲存在棧記憶體裡,而引用資料型別儲存在堆記憶體裡,儲存在棧記憶體的必須是大小固定的資料,引用型別的大小不固定,只能儲存在堆記憶體中,而我們定義的變數實際儲存的是乙個指標,這個指標指向的是堆記憶體。
**解析:
1.基本資料型別拷貝:
當var a = 2的時候在棧記憶體中新開闢了乙個空間儲存a變數值為2,進行var b = a的時候是在記憶體中又開闢了新的空間儲存著b,所以a和b兩個變數互不相關。
2.引用資料型別拷貝:
進行var a = [1,2,3,4]的時候,在棧記憶體中儲存的只是乙個指標也可以說是位址,這個指標指向的是堆記憶體的乙個物件,堆記憶體中儲存著這個物件,當var b = a的時候,我們進行了複製但是複製的只是棧記憶體中的指標,堆記憶體中的本身物件並沒有被複製,所以a[1] = 0的時候,b也改變了,因為a和b指向的是同乙個物件。這就是淺拷貝。
由上總結得出:基本資料型別的拷貝就是直接賦值的操作,而深淺拷貝相對應的就是引用資料型別。
淺拷貝淺拷貝只是拷貝基本型別的資料,如果所拷貝的物件的屬性等於陣列或另乙個物件那就是只拷貝了指標,而沒有拷貝堆記憶體中儲存內容的物件,只要這個物件所改變了,所有指向這個物件的變數的值都會改變。看**:戳這裡
好像看起來都沒錯,doctor物件新增了career 屬性,而nation物件並沒有career 屬性,他們好像沒有什麼關聯,如果我們給屬性的值是乙個物件呢?再來看看:var nation =
;function
extendcopy
(p);
for(
var i in p)
return c;
}var doctor =
extendcopy
(nation)
;doctor.career =
'醫生'
;doctor.nation =
'美國'
;console.
log(doctor.nation)
;// 美國
console.
log(nation.nation)
;// 中國
console.
log(doctor.career)
;// 醫生
哦豁 完蛋, obj1.c[0] = 'bb』執行這一步的時候兩個物件都改變了,為啥執行obj1.c = [『mm』, 「tom」, 「jenny」]的時候兩個物件沒有關聯,因為淺拷貝是只拷貝一層,把 obj1.c作為乙個整體改變了,而obj1.c[0] = 'bb』深層次的物件的改變就需要用到深拷貝了。// 封裝乙個淺拷貝函式:
function
******clone
(initalobj)
;for
(var i in initalobj)
return obj;
}// 定義乙個多層次的物件
var obj =
, c:
["bob"
,"tom"
,"jenny"],
d:function()
}// 賦值obj物件
var obj1 =
******clone
(obj)
; obj1.c =
['mm'
,"tom"
,"jenny"];
// 改變obj1中的c屬性的值
// 列印一下
console.
log(
'obj=>>>'
,obj)
; => ["bob", "tom", "jenny"]
console.
log(
'obj1=>>>'
,obj1)
; => ["mm", "tom", "jenny"]
// 再來改變陣列中的第乙個元素 把上面的賦值和列印注釋一下
obj1.c[0]
='bb'
;// 淺拷貝時,改變屬性的屬性值,改變原物件
// 再列印一下
console.
log(
'obj=>>>'
,obj)
; => ["bb", "tom", "jenny"]
console.
log(
'obj1=>>>'
,obj1)
; => ["bb", "tom", "jenny"]
另外:object.assign()也能實現淺拷貝。
深拷貝深拷貝的實現方式有很多種
最簡單的json方法
json.parse(json.stringify(obj))
使用object.create()方法
遞迴function
deepclone
(initalobj, finalobj)
;for
(var i in initalobj)if(
typeof prop ===
'object'
)else
}return obj;
}
**摘自: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)
;
JS深 淺拷貝
在js中,資料型別分為基本資料型別和引用資料型別兩種。對於基本資料型別來說,它的值直接儲存在棧記憶體中,而對於引用型別來說,它在棧記憶體中只是儲存了乙個指向對記憶體的引用,而真正的資料儲存在堆記憶體中。object array 這兩個就是引用型別,當我門直接去拷貝的話 copyobj obj 拷貝的...
js 深淺拷貝
深拷貝就是複製內部內容 淺拷貝就是複製記憶體位址 var obj 淺拷貝 引用傳遞 淺拷貝就是賦值,將鑰匙複製乙份 var o obj 深拷貝 內部內容複製乙份 將房子複製乙份 方法一 var str json stringify obj var obj3 json parse str 方法二 va...
js深淺拷貝
1.什麼是深淺拷貝 簡單的來說,加入b複製a a改變 如果b也跟著改變的話,那就是淺拷貝,反之是深拷貝 實現淺拷貝方法 1.賦值操作 var a 0 1,2 3,4 var b a a 0 5console log a 5,1,2,3,4 console log b 5,1,2,3,4 2.es6 ...