深拷貝淺拷貝,原型,型別校驗,遞迴深拷貝

2021-10-25 13:28:31 字數 2194 閱讀 5683

遇見乙個問題,解決的時候衍生出了幾條底層原理。為此做一下總結

let arr = ['1', '2', '3', , ]
宣告乙個陣列,要求對陣列進行深拷貝

一 、 深拷貝和淺拷貝的區別

所有基礎資料型別(string,number,null,undefind,boolean)進行賦值時都是深拷貝

所有宣告的變數在賦值引用資料型別時,都是淺拷貝,因為引用資料型別都是存放在堆中,而宣告的變數就相當於乙個指標,指向了堆中的資料,所以在進行賦值的時相當於只複製了指標。當堆中的資料發生改變,指向資料的變數也會發生改變。

而深拷貝就相當於把存放在堆中的資料拿出來在儲存乙份。

常用實現深拷貝的方法有

轉換成json字串,再將其轉換回來

let newarr =

json

.parse

(json

.stringfiy

(arr)

)

遞迴的方法實現深拷貝

object.prototype.

copy

=function

(arr)

for(

let key in arr)

return newarr

}else

}let arr2 =

copy

(arr)

arr[4]

.name =

"王五"

console.

log(arr,arr2)

;

建立乙個copy( )方法放在object的原型上

這裡放張解釋下原型之間的關係

進入遞迴後首先判斷傳遞進來的資料的資料型別,判斷資料型別的方法有

1、 typeof 判斷基礎資料型別,返回乙個字串。無法判斷引用資料型別,因為萬物皆物件,所以在使用typeof 判斷陣列的時候也會返回object

2、instanceof 可以用來判斷引用資料型別

// 例如 判斷arr 是否為陣列

console.

log(arr instanceof

array

)// 返回true //返回boolean型別的值,true或者false

console.

log(obj instanceof

array

)//返回false

//但是當判斷arr 是否為物件時,會返回true,因為陣列也是特殊的物件

console.

log(arr instanceof

object

)//返回true

3、通過原型的construtor屬性判斷資料型別

理應constructor方法可以解決問題了,但是因為undefined和null沒有constructor,所以是不能夠判斷出型別的,並且會報錯

4、object.prototype.tostring.call() 完美解決問題

最後對遞迴實現深拷貝做下解釋

object.prototype.

copy

=function

(arr)

let newarr = object.prototype.tostring.

call

(arr)

.slice(8

,-1)

=="array"?[

]://迴圈arr

for(

let key in arr)

return newarr

}else

}let arr2 =

copy

(arr)

arr[4]

.name =

"王五"

console.

log(arr,arr2)

;

深拷貝淺拷貝 原型及原型鏈 型別校驗

let a b 指向一致,更改a的值會影響blet newarr arr 如果arr結構裡有複雜資料型別的話也是引用object.assign 合併物件 let newarr object.assign arr 返回乙個新的陣列,弊端跟擴充套件運算子拷貝一樣json進行深拷貝 let obj jso...

淺拷貝 深拷貝

copy mutablecopy copy 不管是可變的,還是不可變的,結果都是不可變的 mutablecopy 不管是不可變的,還是可變的,結果都是可變的 nsmutablestring str nsmutablestring stringwithformat a nsarray arr1 str...

深拷貝 淺拷貝

c 中物件的複製就如同 轉殖 用乙個已有的物件快速地複製出多個完全相同的物件。一般而言,以下三種情況都會使用到物件的複製 1 建立乙個新物件,並用另乙個同類的已有物件對新物件進行初始化,例如 cpp view plain copy class rect rect rect1 rect rect2 r...