js对象拷贝的三种⽅法,深拷贝函数。
js 对象拷贝的三种⽅法
以下⾯数据格式obj 为主:
const obj = {
data: 1,
un: undefined,
info: {
d: 2
},
fn: function() {
console.log('Function')
},
get c() {
return info.d
}
}
Object.assign
const ObjA = Object.assign({}, obj)
ObjA.data = 'a'
ObjA.info.d = 'b'
const ObjB = Object.assign({}, obj)
ObjB.data = 'c'
ObjB.info.d = 'd'
console.log(ObjA)
console.log(ObjB)
js assign/*
==========输出==========
{ data: 'a', info: { d: 'd' }, un: undefined, fn: [Function: fn] }
{ data: 'c', info: { d: 'd' }, un: undefined, fn: [Function: fn] }
*/
我们会发现info.d内容相等,说明Object.assign⽆法拷贝深层次内容,适⽤于浅层拷贝。
JSON.stringify & JSON.parse
const ObjA = JSON.parse(JSON.stringify(obj))
ObjA.data = 'a'
ObjA.info.d = 'b'
const ObjB = JSON.parse(JSON.stringify(obj))
ObjB.data = 'c'
ObjB.info.d = 'd'
console.log(ObjA)
console.log(ObjB)
/*
==========输出==========
{ data: 'a', info: { d: 'b' }, c: 2 }
{ data: 'c', info: { d: 'd' }, c: 2 }
*/
我们将源对象转换为字符串,再转换为新对象虽然解决了深层次拷贝的问题,但我们会发现对象中的Function和undefined⽆法拷贝,并且将c: [Getter] 直接转换成了键值对 c:2。
const ObjA = ate(obj)
ObjA.data = 'a'
ObjA.info.d = 'b'
const ObjB = ate(obj)
ObjB.data = 'c'
ObjB.info.d = 'd'
console.log(ObjA)
console.log(ObjB)
console.log(ObjA.__proto__)
console.log(ObjB.__proto__)
/*
==========输出==========
{ data: 'a' }
{ data: 1, info: { d: 'd' }, fn: [Function: fn], c: [Getter] }
{ data: 1, info: { d: 'd' }, fn: [Function: fn], c: [Getter] }
*/
赋值浅层拷贝深层拷贝getter/setter Object.assign ok no no
JSON.stringify ok ok no
深拷贝函数
function checkType(any) {
return String.call(any).slice(8, -1)
}
function clone(any){
if(checkType(any) === 'Object') { // 拷贝对象
let o = {};
for(let key in any) {
o[key] = clone(any[key])
}
return o;
} else if(checkType(any) === 'Array') { // 拷贝数组
var arr = []
for(let i = 0,leng = any.length;i<leng;i++) {
arr[i] = clone(any[i])
}
return arr;
} else if(checkType(any) === 'Function') { // 拷贝函数
return new Function('return '+String()).call(this)
} else if(checkType(any) === 'Date') { // 拷贝⽇期
return new Date(any.valueOf())
} else if(checkType(any) === 'RegExp') { // 拷贝正则
return new RegExp(any)
} else if(checkType(any) === 'Map') { // 拷贝Map 集合
let m = new Map()
any.forEach((v,k)=>{
m.set(k, clone(v))
})
return m
} else if(checkType(any) === 'Set') { // 拷贝Set 集合
let s = new Set()
for(let val of any.values()) {
s.add(clone(val))
}
return s
}
return any;
}
// 测试
var a = {
name: '张三',
skills: ['踢球', '跑步', '打⽻⽑球'],
age: 18,
love: {
name: '⼩红',
age: 16
},
map: new Map([['aaa', '123']]),
fn:function(a){
console.log(`我的名字叫${this.name}` + a)
},
set: new Set([1,2,3,4,5])
}
var newA = clone(a)
a.age = 100
a.love.age = 100
a.set.add('1123')
a.skills.push('计算机')
a.name = '⼩梅'
a.map.set('name', '⼩明')
console.log(a)
console.log(newA)
newA.fn('newA')

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。