1、递归方式
推荐使用,安全不会出错
// 封装深拷贝函数
function deepClode(obj, cache = []) {
if (obj === null || typeof obj != 'object') {
return obj
}
if (Object.prototype.toString.call(obj) === '[object Date]') return new Date(obj)
if (Object.prototype.toString.call(obj) === '[object RegExp]') return new RegExp(obj)
if (Object.prototype.toString.call(obj) === '[object Error]') return new Error(obj)
let item = cache.filter(item => item.oldObj=== obj)[0]
if (item) return item.newObj
let newObj = Array.isArray(obj) ? [] : {}
cache.push({
oldObj: obj,
newObj
})
Object.keys(obj).forEach(key => {
if (typeof obj[key] == "object") {
newObj[key] = deepClode(obj[key], cache)
} else {
newObj[key] = obj[key]
}
});
return newObj
}
// 方法使用
let data = {
num: 1,
fun: () => {
console.log('我是函数')
},
obj: {
key: 'obj',
content: '我是obj'
}
}
let newObj = deepClode(data);
data.num = 2;
console.log(newObj.num); // /输出 1; 不会改变
2、lodash库的cloneDeep()方法
项目中原先有引入lodash库则推荐使用,不然推荐使用第一种递归函数
import lodash from 'lodash';
let data= {
num: 1,
fun: () => {
console.log('我是函数')
},
obj: {
key: 'obj',
content: '我是obj'
}
}
let newObj = lodash.cloneDeep(data);
data.num = 2;
console.log(newObj.b); //输出 1; 不会改变
3、JQuery的extend()方法
let data= {
num: 1,
fun: () => {
console.log('我是函数')
},
obj: {
key: 'obj',
content: '我是obj'
}
}
let newObj = $.extend(true, {}, obj))
obj.num = 2
console.log(newObj.num); // /输出 1; 不会改变
4、JSON.stringify() 和 JSON.parse() 方法
- 时间类型new Date(),序列化之后会变成字符串类型
- undefined、Function,序列化之后会直接丢失
- RegExp类型,序列化后成了 {}
- NaN、Infinity和-Infinity,序列化之后会显示null
- 对象循环引用的时候,会直接报错
5、slice()、扩展运算符… 都是浅拷贝