常用的拷贝方案:
JSON.parse(JSON.stringfily())
Object.assign()
- 递归实现
JSON.parse(JSON.stringfily())
实现深拷贝
const obj = {
a: 1,
b: '1',
c: false,
d: null,
e: undefined,
f: /\d/,
h: {
name: 'helson',
like: ['apple','orange']
},
i: function () { },
j: [1,2,'3',{name: 'helson'}]
}
const obj1 = JSON.parse(JSON.stringify(obj))
console.log(obj1)
// output below
// {
// a: 1,
// b: '1',
// c: false,
// d: null,
// f: {},
// h: { name: 'helson', like: [ 'apple', 'orange' ] },
// j: [ 1, 2, '3', { name: 'helson' } ]
// }
obj
包含了大部分的基础类型和引用类型,将obj进行拷贝之后,发现拷贝的新对象obj1
内缺少了e
属性:类型为undefined
、i
属性:类型为Function
(对象类型)、f
属性正则拷贝之后变成了一个空对象。
总结
优点: 可以拷贝二级对象类型
缺点:
1. 无法拷贝函数
2. 无法拷贝正则
3. 无法拷贝undefined
Object.assign()
实现深拷贝
const obj = {
a: 1,
b: '1',
c: false,
d: null,
e: undefined,
f: /\d/,
h: {
name: 'helson',
like: ['apple','orange']
},
i: function () { },
j: [1,2,'3',{name: 'helson',say: function () { console.log('hi') }}]
}
const obj1 = {}
Object.assign(obj1,obj)
obj.j[3].name = 'helson1'
obj.j[2] ='333'
obj.h.name = 'helson12'
obj.a = 12312
console.log(obj1,obj)
// output below
// {
// a: 1,
// b: '1',
// c: false,
// d: null,
// e: undefined,
// f: /\d/,
// h: { name: 'helson12', like: [ 'apple', 'orange' ] },
// i: [Function: i],
// j: [ 1, 2, '333', { name: 'helson1', say: [Function: say] } ]
// } {
// a: 12312,
// b: '1',
// c: false,
// d: null,
// e: undefined,
// f: /\d/,
// h: { name: 'helson12', like: [ 'apple', 'orange' ] },
// i: [Function: i],
// j: [ 1, 2, '333', { name: 'helson1', say: [Function: say] } ]
// }
根据上面的拷贝案例可以分析得知,Object.create
拷贝的对象内存在二级属性时,二级属性的拷贝为浅拷贝,一级属性为深拷贝。
总结
优点: 可以拷贝属性值为null
、undefined
、正则的属性
缺点: 无法拷贝二级属性
递归实现拷贝
function _deepClone(source) {
let target;
if (typeof source === 'object') {
target = Array.isArray(source) ? [] : {}
for (let key in source) {
if (source.hasOwnProperty(key)) {
if (typeof source[key] !== 'object') {
target[key] = source[key]
} else {
target[key] = _deepClone(source[key])
}
}
}
} else {
target = source
}
return target
}
实现的思想就是遍历拷贝的对象,对属性进行类型判断,如果为对象则递归。
总结
优点: 可以拷贝任何类型属性值的属性
缺点: 需要递归浪费性能