對于原始數據類型,并沒有深淺拷貝的區別,深淺拷貝都是對于引用數據類型而言,如果我們要賦值對象的所有屬性都是引用類型可以用淺拷貝
?淺拷貝:只復制一層對象,當對象的屬性是引用類型時,實質復制的是其引用,當引用值發生改變時,也會跟著改變
深拷貝:深拷貝是另外申請了一塊內存,內容和原來一樣,更改原對象,拷貝對象不會發生改變
1、 淺拷貝實現
?for in 遍歷實現
let shallCopy => obj=>{let rst={}for(let key in obj){//只復制本身的屬性(非繼承過來的屬性)枚舉屬性if(obj.hasOwnProperty(key)){rst[key]=obj[key]}}return rst}let start ={name:'古力娜扎',age:'22',friend:{name:'鄧超'}}let copyStart=shallCopy(start)copyStart.name="熱巴"copyStart.friend.name='黃渤'// 拷貝的第一層層如果是引用類型,拷貝的其實是一個指針,所以拷貝對象改變會影響原對象console.log(start.name,opyStart.friend.name) //古力娜扎 黃渤
Object.assign(target,source) (適用于對象)
可以把 n 個源對象拷貝到目標對象中去(拷貝的是可枚舉屬性)
let start = {name: '古力娜扎',age: '22',friend: {name: '鄧超'}
}
let returnedTarget = Object.assign({}, start)
?擴展運算符...
let start = { name: '劉亦菲' }
let newStart = { ...start }
newStart.name = '迪麗熱巴'
console.log(start.name) // 劉亦菲
?slice(適用于數組)
let a = [1, 2, 3, 4]
let b = a.slice()
b[0] = 9
console.log(a) //[1,2,3,4]
3 、深拷貝實現
JSON.parse(JSON.string(obj))
let obj = {name: '小明',dog: ['小花', '旺財']
}let obj1 = JSON.parse(JSON.stringify(obj))
obj1.name = '小華'
obj1.dog[0] = '小白'
console.log(obj) // {name: "小明", dog: ['小花', '旺財']}
// 原數組并沒有改變,說明實現了深拷貝let richGirl = [{name: '開心',car: ['寶馬', '奔馳', '保時捷'],deive: function() {},age: undefined}
]let richBoy = JSON.parse(JSON.stringify(richGirl))
console.log(richBoy)
/*1. 當屬性值為undefined或函數,則序列化的結果會把函數或 undefined丟失2. 對象中存在循環引用的情況也無法正確實現深拷貝3. Symbol,不能被JSON序列化4. RegExp、Error對象,JSON序列化的結果將只得到空對象5. 會丟失對象原型*/
?遞歸實現深拷貝
let deepClone = obj => {let newObj = Array.isArray(obj) ? [] : {}if (obj && typeof obj === 'object') {for (let key in obj) {if (obj.hasOwnProperty(key)) {if (obj[key] && typeof obj[key] === 'object') {newObj[key] = deepClone(obj[key])} else {// 如果不是對象直接拷貝newObj[key] = obj[key]}}}}return newObj
}let richGirl = {name: '開心',car: ['寶馬', '奔馳', '保時捷'],deive: function() {},age: undefined
}let richBoy = deepClone(richGirl)richBoy.deive = '渣男開大G'
richBoy.name = '小明'
richBoy.car = ['哈羅單車', '膜拜']
richBoy.age = 20console.log(richGirl)
console.log(richBoy)
4、 第三方庫實現拷貝
//cloneDeep: 深拷貝 clone:淺拷貝,此例子介紹深拷貝
const _ = require('lodash') //全部引入
const cloneDeep = require('lodash/cloneDeep') //引入單個方法,用的方法少建議用這種方式引入
let obj = {name: '開心',car: ['寶馬', '奔馳', '保時捷'],deive: function() {},age: undefined
}
const newObj = cloneDeep(obj)
newObj.name = '不開心'
newObj.car[0] = '自行車'
console.log(obj, newObj) // 原對象不會改變