1. json.parse(json.stringfy()) 一般使用 对于不同数据的返回
var Obj = {
func: function () { alert(1) },
obj: {a:1},
arr: [1,2,3],
und: undefined,
reg: /123/,
date: new Date(0),
NaN: NaN,
infinity: Infinity,
sym: Symbol(1)
}
Object.defineProperty(Obj,'innumerable',{
enumerable:false,
value:'innumerable'
})
JSON.parse(JSON.stringfy(Obj));
—注意
拷贝的对象的值中如果有函数、undefined、symbol 这几种类型,经过 JSON.stringify 序列化之后的字符串中这个键值对会消失;
无法拷贝对象的原型链、不可枚举的属性,以及对象的循环应用,即对象成环 (obj[key] = obj);
拷贝 Date 引用类型会变成字符串;
拷贝 RegExp 引用类型会变成空对象;
对象中含有 NaN、Infinity 以及 -Infinity,JSON 序列化的结果会变成 null;
该方法未拷贝对象所有属性,但是足以满足日常开发去需求
2.递归版深拷贝 – 可完全复制拷贝数据
//需要拷贝的对象
var obj = {
num: 0,
str: '',
boolean: true,
unf: undefined,
nul: null,
obj: { name: '对象', id: 1, gender: 1 },
arr: [0, 1, 2],
func: function () { console.log('函数') },
date: new Date(0),
reg: new RegExp('/正则/ig'),
[Symbol('1')]: 1,
};
Object.defineProperty(obj, 'innumerable', {
enumerable: false, value: '不可枚举属性' }
);
obj = Object.create(obj, Object.getOwnPropertyDescriptors(obj))
obj.loop = obj // 设置loop成循环引用的属性
//判断数据类型
function ifType(val){
let type = typeof val;
if (type !== "object") {
return type;
}
return Object.prototype.toString.call(val).replace(/^\[object (\S+)\]$/, '$1');
}
//拷贝代码
const deepClone = function (obj, hash = new WeakMap()) {
if (ifType(obj) === 'Date')
return new Date(obj) // 日期对象直接返回一个新的日期对象
if (ifType(obj) === 'RegExp')
return new RegExp(obj) //正则对象直接返回一个新的正则对象
//如果循环引用了就用 weakMap 来解决
if (hash.has(obj)) return hash.get(obj)
let allDesc = Object.getOwnPropertyDescriptors(obj)
//遍历传入参数所有键的特性
let copyObj = Object.create(Object.getPrototypeOf(obj), allDesc)
//继承原型链
hash.set(obj, copyObj)
const isType = obj => (typeof obj === 'object' || typeof obj === 'function') && (obj !== null)
for (let key of Reflect.ownKeys(obj)) {
copyObj[key] = (isType(obj[key]) && typeof obj[key] !== 'function') ? deepClone(obj[key], hash) : obj[key]
}
return copyObj
}
//验证
let copyObj = deepClone(obj)
copyObj.arr.push(4)
console.log('原始对象obj', obj)
console.log('拷贝后的对象copyeObj', copyObj)
结果如图所示
除上以外,函数库lodash提供的_.cloneDeep方法也可以实现深拷贝