JavaScript中淺拷貝和深拷貝的區別和實現

要理解 JavaScript中淺拷貝和深拷貝的區別,首先要明白JavaScript的數據類型前端

JavaScript有兩種數據類型,基礎數據類型引用數據類型微信

基礎數據類型:保存在棧內存中的簡單數據段 ,有undefined,boolean,number,string,null
引用數據類型:Array,對象,Function 保存在堆內存空間中

圖片描述

var a1 = 0; var a2 = 'this is str'; var a3 = null 存放在棧內存中
var c =[1,2,3] 與 var d = {m:20} 變量名與內存地址存儲在棧內存中,[1,2,3]與{m:20} 做爲對象存儲在堆內存中this

基礎數據類型的複製(如var a = 20 var b = a)
圖片描述spa

引用數據類型的複製 ( var m ={a:10, b:20} var n = m)
圖片描述prototype

解釋:
m與n指向同一個內存空間,當m或者n改變時,另外一個也跟着改變
如m.a = 80 ; console.log(n.a) // 80設計

怎麼樣使引用數據類型有各自獨立的內存空間?指針

1、採用遞歸的方法複製拷貝對象code

function deepclone(obj) {
        let objClone = Array.isArray(obj) ? [] : {};
        if (obj && typeof obj === "object") {
            for (key in obj) {
                //if (obj.hasOwnProperty(key)) {   //也能夠不加
                    if (obj[key] && obj[key] === "object") {
                        objClone[key] = deepclone(obj[key])
                    } else {
                        objClone[key] = obj[key]
                    }
                //}
            }
        }
        return objClone
    }
    var a = [1, 2, 3, 4];
    var b = deepclone(a);
    a[0] = 8
    console.log(a, b);

圖片描述

Array.isArray(obj):ECMAScript 5.1 (ECMA-262)   考慮到的兼容性,能夠用下面的方法實現較好的兼容
   if (!Array.isArray) {
      Array.isArray = function(arg) {
    return Object.prototype.toString.call(arg) === '[object Array]';
     };
}

2、用JSON.stringify把對象轉成字符串,再用JSON.parse把字符串轉成新的對象。對象

function deepclone(obj){
      var _obj = JSON.stringify(obj);
      var cloneObj = JSON.parse(_obj);
      return cloneObj
    }
    var a =[1,2,3,4];
    var b= deepclone(a);
    a[0]=8
    console.log(a,b);
    //能夠用JSON.stringify與JSON.parse實現深拷貝的緣由是JSON.stringify(obj)轉換成字符串,變成基本數據類型,基本類型拷貝是直接在棧內存新開空間,直接複製一份名-值,不影響以前的對象

總結:blog

淺拷貝(shallow copy):只複製指向某個對象的指針,而不復制對象自己,新舊對象共享一塊內存;   

深拷貝(deep copy):複製並建立一個一摸同樣的對象,不共享內存,修改新對象,舊對象保持不變;實現深拷貝主要有2種方法

(1)遞歸

(2)JSON.stringify結合JSON.parse

微信公衆號:前端之攻略
發佈前端與設計有關的內容,請掃描下面二維碼
圖片描述

相關文章
相關標籤/搜索