浅拷贝
- 浅拷贝的意思就是只复制引用,而未复制真正的值。
const fruitsObj = {
apple:'12个',
banana:'10个',
orange:{
big:'10个',
little:'20个'
},
}
// 浅拷贝方法
const shallowClone = originObj=> {
var targetObj = {};
for(let key in originObj) {
if (originObj.hasOwnProperty(key)) {
targetObj[key] = originObj[key];
}
}
return targetObj;
}
const _fruitsObj = shallowClone(fruitsObj) // 浅拷贝
console.log(_fruitsObj===fruitsObj,'..._fruitsObj===fruitsObj') // false
_fruitsObj.apple='22个' // 第一层,原对象第一层没有改变
_fruitsObj.orange.big='5个' // 第二层,原对象第二层改变了
深拷贝
- 目前实现深拷贝的方法不多,主要是两种:
- 利用 JSON 对象中的 parse 和 stringify --- 性能最快
- 利用递归来实现每一层都重新创建对象并赋值
1. JSON.parse(JSON.stringify())**
const animalObj = {
birds:['chicken','duck'],
lactation:['dog','cat'],
}
const _animalObj =JSON.parse(JSON.stringify(animalObj)) // 深拷贝
console.log(_animalObj===animalObj) // false
_animalObj.lactation=['pig'] // 修改_animalObj中lactation的值
console.log(_animalObj,animalObj) // _animalObj更改了,animalObj没有更改
- JSON.parse(JSON.stringify())很好用但是,但是有些情况不能使用
- 具有循环引用的对象时,报错
- 当值为函数、undefined、或symbol时,无法拷贝
2. 利用递归来实现每一层都重新创建对象并赋值**
function deepClone(originObj){
const targetObj = originObj.constructor === Array ? [] : {}; // 判断复制的目标是数组还是对象
for(let keys in originObj){ // 遍历目标
if(originObj.hasOwnProperty(keys)){ // // hasOwnProperty判断是否为自身属性
if(originObj[keys] && typeof originObj[keys] === 'object'){ // 如果值是对象,就递归一下
targetObj[keys] = originObj[keys].constructor === Array ? [] : {}
targetObj[keys] = deepClone(originObj[keys]);
}else{ // 如果不是,就直接赋值
targetObj[keys] = originObj[keys]
}
}
}
return targetObj
}
const PetsObj = {
cat:'猫咪',
pig:['小猪佩奇','乔治'],
dog:{
1:'柯基',
2:'藏獒'
},
snake:()=>{
console.log('一条蓝色的小蛇')
},
cow:undefined,
sheep:Symbol()
}
const _PetsObj = deepClone(PetsObj)
console.log(_PetsObj===PetsObj) //false
_PetsObj.pig='小猪佩奇'
console.log(_PetsObj,PetsObj) // PetsObj没有更改
如何实现浅拷贝
1、concat(value)
const obj1 = ['a',{b:'c'},'d']
const _obj1 = [].concat(obj1)
console.log(_obj1===obj1) // false
_obj1[0]='aaa'
_obj1[1].b='ccc'
console.log(obj1) // ['a',{b:'ccc'},'d']
2、value.slice()
const obj2 = ['a',{b:'c'},'d']
const _obj2 = obj2.slice()
console.log(obj2===_obj2) // false
_obj2[0]='aaa'
_obj2[1].b='ccc'
console.log(obj2) // ['a',{b:'ccc'},'d']
3、Object.assign(value)
const obj3 = {
a:'1',
b:{
c:1
}
}
const _obj3 = Object.assign(obj3)
console.log(obj3===_obj3,'....obj3===_obj3') // true
_obj3.a = '111' // 第一层
_obj3.b.c = {d:'123'} // 第二层
console.log(obj3) // {a:'111',b:{c:{d:'123'}}} // 都更改了
4、展开运算符... 实现的是对象第一层的深拷贝
const obj4 = {
a:'1',
b:{
c:1
}
}
const _obj4 = {...obj4}
console.log(_obj4===obj4) // false
_obj4.a = '111' // 第一层
_obj4.b.c = {d:'123'} // 第二层
console.log(obj4) // {a:'1',b:{c:{d:'123'}}}
5、lodash中的_.clone(value)
var _ = require('lodash');
const obj5 = {
a: '1',
b: {
c: 1,
},
}
const _obj5 = _.clone(obj5)
console.log(_obj5 === obj5) // false
_obj5.a = '111' // 第一层
_obj5.b.c = {d: '123'} // 第二层
console.log(obj5) // {a:'1',b:{c:{d:'123'}}}
如何实现深拷贝
1、JSON.parse(JSON.stringfy(value))
const animalObj = {
birds:['chicken','duck'],
lactation:['dog','cat'],
}
const _animalObj =JSON.parse(JSON.stringify(animalObj)) // 深拷贝
console.log(_animalObj===animalObj) // false
_animalObj.lactation=['pig'] // 修改_animalObj中lactation的值
console.log(_animalObj,animalObj) // _animalObj更改了,animalObj没有更改
2、lodash中的_.cloneDeep(value)
var _ = require('lodash');
const obj6 = {
a: '1',
b: {
c: 1,
},
}
const _obj6 = _.cloneDeep(obj6)
console.log(_obj6 === obj6) // false
_obj6.a = '111' // 第一层
_obj6.b.c = {d: '123'} // 第二层
console.log(obj6) // {a:'1',b:{c:1}}
3、手写递归
function deepClone(originObj){
const targetObj = originObj.constructor === Array ? [] : {}; // 判断复制的目标是数组还是对象
for(let keys in originObj){ // 遍历目标
if(originObj.hasOwnProperty(keys)){ // // hasOwnProperty判断是否为自身属性
if(originObj[keys] && typeof originObj[keys] === 'object'){ // 如果值是对象,就递归一下
targetObj[keys] = originObj[keys].constructor === Array ? [] : {}
targetObj[keys] = deepClone(originObj[keys]);
}else{ // 如果不是,就直接赋值
targetObj[keys] = originObj[keys]
}
}
}
return targetObj
}
本文使用 mdnice 排版