深入理解對象的引用

首先我們來講一下賦值關系和引用關系

  • 賦值關系
var a = 5;
var b =a;
b+ = 3;
alert(b);//8
alert(a);//5

a和b是簡單的賦值關系,這種賦值關系存在于基本類型中

  • 對于函數(shù)和對象,存在的不是簡單的賦值關系,而是引用關系

我們來看兩種情況

var a = [1,2,3]
var b = a;
b.push(4);
alert(a)//1,2,3,4
alert(b)//1,2,3,4

在這種情況下,a和b共用一個內存空間。就像我們c語言中的指針。用一種更形象的說法:a與b都有一個存庫的門,所以他們都能改變這個倉庫,都改變的是同一個倉庫。

var a = [1,2,3];
var b = a;
b = [1,2,3,4];
alert(a)//1,2,3
alert(b)//1,2,3,4

這種情況就和剛才有點不同了。你或許會想,ab不是共用一個內存嗎,為什么b變了a不跟著變。
在這里我們就要注意這兩句的區(qū)別了

b.push(4);
b = [1,2,3,4];

前面一句是用數(shù)組方法向倉庫里放了一個4,所以ab呈現(xiàn)出來的都是1234畢竟他們用的是一個倉庫。而后面一句b = [1,2,3,4];而是創(chuàng)建了一個新數(shù)組,重新放入1,2,3,4,這時候他已經和a沒有關系了,他放入的前三個數(shù)甚至可以不是和a一樣的123了。

我覺得這兩個例子就像這樣的一個故事:a和b是一對父子,小時候b和爸爸a一起生活,有時為家里添置一點小家具;后來b長大了就自己買房子了,自己可以把房子裝修得完全不一樣了。(個人理解,幫助記憶而已,不必深究)

了解了對象的引用關系,下面我們來談談怎樣復制對象

對象的拷貝有兩種方式,我們稱為深拷貝和淺拷貝,淺拷貝就是只復制最表面的那一層對象,我們來看下面這個例子

var obj = {
    a:10
}
function copy() {//淺拷貝
    var newObj = {};
    for(var attr in obj) {
        newObj[attr] = obj[attr];
    }
    return newObj;
}

var obj2 = copy(obj);
obj2.a = 20;
alert(obj.a)//10

在這個例子中,我定義了一個拷貝的函數(shù),這個函數(shù)的思路是:把所有a中的屬性都復制到b中去,然后返回一個新對象。因為obj對象中只有一層,所以obj2拷貝成功。

我們再來看看原對象不止一層的情況

var objX = {
    a:{b:10}
}
var objY = copy(objX);
objy.a.b = 20;
alert(objX.a.b)//20 復制失敗

這里我們還是使用的上面的拷貝函數(shù)。我們可以看到,這一次就拷貝失敗了。這就是我說的淺拷貝這能拷貝一層對象。

下面我們來看深拷貝

深拷貝其實拷貝的原理和淺拷貝是一樣的,我們需要做到的就是把每一層對象都拷貝過去。這里我采用遞歸的方法。

遞歸應該大家都知道,到可能概念模模糊糊,所以我先簡單的介紹一下遞歸。

  • 遞歸

遞:傳遞

歸:回到之前的位置

image.png

我們來看一個求階層的例子

function test(n) {
    return n*test(n-1);
}

我們要在它返回的時候再去執(zhí)行它本身,每次傳進的參數(shù)會小1.當然,這傳遞的運算必須要有一個結束的時候,所以我們要進行判斷什么時候結束

function test(n) {
    if(n==1) {
        return 1;
    }
    return n*test(n-1);
}

這里在n=1時函數(shù)就執(zhí)行結束了。

所以總結遞歸的兩個點

  1. 函數(shù)調用函數(shù)自身,執(zhí)行遞的動作
  2. 最后一次判斷一個終止條件,可以執(zhí)行的動作

然后我們的深拷貝就開始了

function deepCopy(obj) {
    if(typeof obj != 'object') {
        return obj;
    }
    var newObj = {};
    for(var attr in obj) {
        newObj[attr] = deepCopy(obj[attr]);
    }
    return newObj;
}

在這里,我們一層一層的往下剝,剝到不是對象的時候就停止了,也就實現(xiàn)了深拷貝

如果你對我的文章有想說的話,歡迎qq交流:425910502.在這里附上qq主要是因為經常在網上看一些文章,有問題想問作者又得不到作者即使的回復,讓人很懊惱,雖然我的文章并不會被很多人看到,但我要對看到我文章的人負責。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容