本文在 魏秋娟 小姐姐的博客基础上,经过我的一些整理重新发布,
参考原文链接https://blog.csdn.net/qq_39083004/article/details/80206336
var obj = {
name: 'a',
arr:[1,2,3]
}
var newObj = JSON.parse(JSON.stringify(obj))
newObj.name = "cc"
console.log(obj) //{ name: 'a', arr: [ 1, 2, 3 ] }
console.log(newObj) //{ name: 'cc', arr: [ 1, 2, 3 ] }
对于一般常用的数据拷贝这种方法无疑是非常简单的,但是遇到复杂的数据,比如
date
,正则,函数,值为undefinde
的对象时键值对直接被删除,就会出现问题
可以根据业务返回数据类型,来酌情使用
var obj = {
name: 'a',
arr:[1,2,3],
date: [new Date(1536627600000), new Date(1540047600000)],
RegExp: new RegExp('\\w+'),
job:undefined
}
var newObj = JSON.parse(JSON.stringify(obj))
newObj.name = "cc"
console.log(obj) //{ name: 'a',
// arr: [ 1, 2, 3 ],
// date: [ 2018-09-11T01:00:00.000Z, 2018-10-20T15:00:00.000Z ],
// RegExp: /\w+/,
// job: undefined }
console.log(newObj) //{ name: 'cc',
// arr: [ 1, 2, 3 ],
// date: [ '2018-09-11T01:00:00.000Z', '2018-10-20T15:00:00.000Z' ],日期格式变为字符串了
// RegExp: {} } 正则变成了空对象,值为undefinde的键值对直接被删除
function deepClone(obj) {
var result = {}
if (obj && typeof obj === 'object') {
for (let key in obj) {
if (obj[key] && typeof obj[key] === 'object') {
result[key] = deepClone(obj[key]);//如果对象的属性值为object的时候,递归调用deepClone,即把某个值对象复制一份到新的对象的对应值中。
} else {
result[key] = obj[key];//如果对象的属性值不为object的时候,直接复制键值对到新的对象。
}
}
return result;
}
return obj;
}
let obj = {
name:'lily',
arr:[1,2,3],
date: [new Date(1536627600000), new Date(1540047600000)],
RegExp: new RegExp('\\w+'),
job:undefined,
obj2:{
fun:function(){}
}
};
let testObj = deepClone(obj);
testObj.name = '不知火舞';
console.log(obj); //{ name: 'lily',
// arr: [ 1, 2, 3 ],
// date: [ 2018-09-11T01:00:00.000Z, 2018-10-20T15:00:00.000Z ],
// RegExp: /\w+/,
// job: undefined,
// obj2: { fun: [Function: fun] } }
console.log(testObj) //{ name: '不知火舞',
// arr: { '0': 1, '1': 2, '2': 3 },
// date: { '0': {}, '1': {} }, 日期对象也变成了空对象
// RegExp: {}, /* 正则依然时空对象 */
// job: undefined,
// obj2: { fun: [Function: fun] } }
这种遍历方法相比JSON方法,函数,和值为
undefinde
的键值对可以正常复制了,但是正则,和日期对象依然是不能复制的,怎么才能全部复制呢?
还得找找!!
function deepClone(obj) {
let copy = Object.create(Object.getPrototypeOf(obj));
let propertyNames = Object.getOwnPropertyNames(obj);
propertyNames.forEach(function (items) {
let item = Object.getOwnPropertyDescriptor(obj, items);
Object.defineProperty(copy, items, item);
});
return copy;
}
let obj = {
name:'lily',
arr:[1,2,3],
date: [new Date(1536627600000), new Date(1540047600000)],
RegExp: new RegExp('\\w+'),
job:undefined,
obj2:{
fun:function(){}
}
};
let testObj = deepClone(obj);
testObj.name = '不知火舞';
console.log(obj); //{ name: 'lily',
// arr: [ 1, 2, 3 ],
// date: [ 2018-09-11T01:00:00.000Z, 2018-10-20T15:00:00.000Z ],
// RegExp: /\w+/,
// job: undefined,
// obj2: { fun: [Function: fun] } }
console.log(testObj) //{ name: '不知火舞',
// arr: [ 1, 2, 3 ],
// date: [ 2018-09-11T01:00:00.000Z, 2018-10-20T15:00:00.000Z ],
// RegExp: /\w+/,
// job: undefined,
// obj2: { fun: [Function: fun] } }
这个方法目测可以拷贝到我所关注到的所有对象属性,但是涉及到的知识我不怎么懂,需要再研究下Object的自带属性知识。。
如果有大神路过我这个博客,对于第三种方法有易懂的解释,请不吝留言,感谢!!