深拷貝和淺拷貝-深度解析

前言

對於 數字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 obj1 = 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);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章