遇見乙個問題,解決的時候衍生出了幾條底層原理。為此做一下總結
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...