话不多说,直接上实现方法。。。。。。
方法一: 使用 jQuery.extend() 方法 -- jQuery.extend([deep,]target,object1[,objectN])
jQuery.extend() 方法将一个或多个对象的内容合并到目标对象target中,如果target参数被省略,则目标对象默认为jQuery对象本身;如果多个对象中具有相同的属性,则后者会覆盖前者的属性值。
需要留意的是第一个参数deep参数,该参数默认值为false,表示不深度合并,可将其值改为true,实现深度拷贝。
示例:
let sub = { password: '123456' }; let obj = { name: "admin", age: 18, sub: sub }; /* let obj2 = $.extend({},obj); // obj2 = {name: "admin", age: 18, sub: {password: "123456"}} obj2.name = 'test'; obj2.sub.password = '111111'; console.log(obj); // {name: "admin", age: 18, sub: {password: "111aaa"}} console.log(obj2); // {name: "test", age: 18, sub: {password: "111aaa"}} */ let obj3 = $.extend(true, {}, obj); // obj3 = {name: "admin", age: 18, sub: {password: "123456"}} obj3.name = 'test'; obj3.sub.password = '111111'; console.log(obj); // {name: "admin", age: 18, sub: {password: "123456"}} console.log(obj3); // {name: "test", age: 18, sub: {password: "111aaa"}}
方法二: 使用 JSON.stringify 先把对象序列化,再用 JSON.parse() 反序列化
使用该方法具有一定的局限性,该局限性是由 JSON.stringify() 序列化方法自身的局限带来的。简单来说局限性体现在:
- undefined、任意的函数以及 symbol 值,在序列化过程中会被忽略(出现在非数组对象的属性值中时)或者被转换成 null(出现在数组中时)。函数、undefined 被单独转换时,会返回 undefined,如JSON.stringify(function(){}) or JSON.stringify(undefined);
- Date 日期格式的数据会被转成字符串处理,JSON.parse() 反序列化无法还原为 Date 格式;
- NaN 和 Infinity 格式的数值及 null 都会被当做 null。
- 其他类型的对象,包括 Map/Set/WeakMap/WeakSet,仅会序列化可枚举的属性
有关 JSON.stringify() 的更多使用细节可浏览: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
示例:
let sub = { password: '123456' }; let obj = { name: "admin", age: 18, sub: sub }; let obj2 = JSON.parse(JSON.stringify(obj)); // obj2 = {name: "admin", age: 18, sub: {password: "123456"}} obj2.name = 'test'; obj2.sub.password = '111111'; console.log(obj); // {name: "admin", age: 18, sub: {password: "123456"}} console.log(obj2); // {name: "test", age: 18, sub: {password: "111aaa"}}
方法三: 采用递归的方式实现
function deepCopy(obj) { let result = Array.isArray(obj) ? [] : {}; for (const key in obj) { if(typeof obj[key] == 'object' && obj[key] !== null) { result[key] = deepCopy(obj[key]); } else { result[key] = obj[key]; } } return result; }
注意:使用 ES6 的对象扩展运算符、Object.assign() 等方法不能算是完整的深度拷贝使用需谨慎。。。
示例:
let sub = { password: '123456' }; let obj = { name: "admin", age: 18, sub: sub }; /*let obj2 = { ...obj };*/ let obj2 = Object.assign({}, obj); console.log(obj2); // obj2 = {name: "admin", age: 18, sub: {password: "123456"}} obj2.name = 'test'; obj2.sub.password = '111aaa'; console.log('-----------'); console.log(obj); // {name: "admin", age: 18, sub: {password: "111aaa"}} console.log(obj2); // {name: "test", age: 18, sub: {password: "111aaa"}}