对于原始数据类型,并没有深浅拷贝的区别,深浅拷贝都是对于引用数据类型而言,如果我们要赋值对象的所有属性都是引用类型可以用浅拷贝
浅拷贝:只复制一层对象,当对象的属性是引用类型时,实质复制的是其引用,当引用值发生改变时,也会跟着改变
深拷贝:深拷贝是另外申请了一块内存,内容和原来一样,更改原对象,拷贝对象不会发生改变
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) //古力娜扎 黄渤
可以把 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) // 刘亦菲
let a = [1, 2, 3, 4]
let b = a.slice()
b[0] = 9
console.log(a) //[1,2,3,4]
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 = 20
console.log(richGirl)
console.log(richBoy)
//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) // 原对象不会改变