乐趣区

深拷贝和浅拷贝-深度解析

前言
对于 数字,boolean 和 字符串 等基本类型 而言,赋值、浅拷贝和深拷贝无意义,因为每次都会在堆中开辟一块新的空间,指向新的地址。
一、赋值:
指向同一个地址,不拷贝。
var obj1 = {name:’ 圆 ’, radius:10, point:{x:0,y:0}};
var obj2 = obj1;

obj2.name = “ 圆 2 ″; //obj1 中的 name 也会变
二、浅拷贝:

var obj1 = {name:’ 圆 ’, radius:10, point:{x:0,y:0}};
var obj2 = Object.assign({},obj1);

obj2.name=” 圆 2 ” // obj1.name 不会变
obj2.point.x = 2 //obj1.point.x 改变,因为只拷贝到 point 一层

同样,解构赋值也是如此
var obj1 = {name:’ 圆 ’, radius:10, point:{x:0,y:0}};
var obj2 = {…obj1}
三、深拷贝:

方法 1
JSON.stringify(obj) 先将对象转换为字符串 JSON.parse(str) 然后再将字符串转为对象。
var obj1 = {name:’ 圆 ’, radius:10, point:{x:0,y:0}};
var obj2 = JSON.stringify(obj1);
var obj2 = JSON.parse(obj2);

obj2.name = “ 圆 2 ”; // obj1 不变
obj2.point.x = 3; // obj1 不变
但 JSON.stringify 在转换 Date,RegExp 对象及 function 时会出现问题,同时也会忽略 undefined、function。
//date 类型
var o = new Date();
console.log(o.toString()); // Mon Nov 06 2017 11:23:35 GMT+0800 (China Standard Time) 本地标准时间
console.log(JSON.stringify(o)); // “2017-11-06T03:23:35.547Z” 国际标准时间
因为 stringify 默认调用的是 Object 的 toJSON 方法,所以重写 Date 的 toJSON,然后 stringify 就是 ok 的。
Date.prototype.toJSON = function () {
return this.toLocaleString();
}
console.log(JSON.stringify(o)); // “11/6/2017, 11:23:35 AM”
同理 RegExp
//RegExp 类型
r1 = /\d+/;
console.log(JSON.stringify(r1)); // {}

RegExp.prototype.toJSON = function(){
return this.toString();
}
console.log(JSON.stringify(r1)); // “/\\d+/”
方法 2
类库的方式。jquery,lodash 等库
//jquery
let y = $.extend(true,{},x) // 第一个参数 必须为 true

//lodash 库
let y = _.cloneDeep(x);

退出移动版