JavaScript - 堆與棧府蔗、淺拷貝與深拷貝

堆與棧是什么晋控,與淺拷貝和深拷貝有什么聯(lián)系?

在計算機領(lǐng)域姓赤,堆棧是兩種數(shù)據(jù)結(jié)構(gòu)赡译,都是一種數(shù)據(jù)項按序排列的數(shù)據(jù)結(jié)構(gòu),只能在一端(稱為棧頂(top))對數(shù)據(jù)項進行插入和刪除不铆。

深拷貝和淺拷貝的主要區(qū)別就是其在內(nèi)存中的存儲類型不同蝌焚,而堆和棧都是內(nèi)存中劃分出來用于存儲的區(qū)域。

棧(stack)為系統(tǒng)自動分配的內(nèi)存空間誓斥,它由系統(tǒng)自動釋放只洒;而堆(heap)則是動態(tài)分配的內(nèi)存,大小不定也不會自動釋放劳坑。

ECMAScript 的數(shù)據(jù)類型

因此在了解淺拷貝與深拷貝之前毕谴,我們先來了解一下ECMAScript 中的數(shù)據(jù)類型。

基本類型

基本類型主要有:undefined距芬,boolean涝开,number,string框仔,null

基本類型是存放在內(nèi)存中的簡單數(shù)據(jù)段舀武,數(shù)據(jù)大小確定,內(nèi)存空間大小可以分配离斩,直接按值存放的银舱,所以可以直接訪問瘪匿。

引用類型

引用類型主要有:object,array寻馏,function

引用類型是存放在內(nèi)存中的對象棋弥。變量實際在內(nèi)存中保存了一個指針,這個指針指向中的一個空間操软。每個空間大小不一樣嘁锯,要根據(jù)情況來進行特定的分配。當我們需要訪問引用類型的值時聂薪,首先從中獲得該對象的地址指針家乘,然后再從內(nèi)存中取得所需的數(shù)據(jù)。

基本類型與引用類型的主要區(qū)別

基本類型與引用類型最大的區(qū)別實際就是傳值傳址的區(qū)別 藏澳。

var a = [1,2,3,4,5];
var b = a; //傳址
var c = a[0]; //傳值
console.log(b); //1,2,3,4,5
console.log(c); //1
b[4] = 6; //改變b數(shù)組的某一項值
c = 7; //改變c的值
console.log(a[4]); //6 
console.log(a[0]); //1

從上面我們可以得知仁锯,當我改變b數(shù)組時,a數(shù)組也發(fā)生了變化翔悠。但是當我改變c的值時业崖,a卻沒有發(fā)生改變。這就是傳值與傳址的區(qū)別蓄愁。

因為a是數(shù)組双炕,屬于引用類型,所以它賦予給b的時候傳的是棧中的地址(相當于新建了一個不同名“指針”)撮抓,而不是堆內(nèi)存中的對象妇斤,所以a和b是指向同一個堆內(nèi)存。而c僅僅是從a堆內(nèi)存中獲取的一個數(shù)據(jù)值丹拯,并保存在棧中站超。所以當b修改的時候,會根據(jù)地址回到a堆內(nèi)存中修改乖酬,而c則直接在棧中修改死相,并且不能指向a堆內(nèi)存中。

image

淺拷貝

有上面的內(nèi)容可以知道咬像,在定義一個對象或數(shù)組時算撮,變量存放的往往只是一個堆地址。當我們使用對象拷貝時县昂,如果屬性是對象或數(shù)組時肮柜,這時候我們傳遞的也只是一個堆地址。因此子對象在訪問該屬性時七芭,會根據(jù)地址回溯到父對象指向的堆內(nèi)存中素挽,即父子對象發(fā)生了關(guān)聯(lián) 蔑赘,兩者的屬性值會指向同一內(nèi)存空間狸驳。

image

例子:

var a = {
  key1: 123,
  key2: [1,2]
};
function copy(o){
  var obj = {};
  for(var i in o){
    obj[i] = o[i];
  }
  return obj;
}
var b = copy(a);
b.key1 = 1234; //b對象的key1重新賦值
b.key2.push(3); //b對象的key2數(shù)組里面插入一個新的值
console.log(b.key1); //1234
console.log(a.key1): //123
console.log(b.key2); //1,2,3
console.log(a.key2); //1,2,3

上述代碼中预明,可以看出b的key1值改變了但是a的key1的值沒有隨著發(fā)生改變,但b的key2值改變后卻導(dǎo)致a的key2的值也發(fā)生了改變耙箍。

這是因為key1的值屬于基本類型撰糠,所以拷貝的時候傳遞的就是該數(shù)據(jù)段。但是key2的值是堆內(nèi)存中的對象辩昆,所以key2在拷貝的時候傳遞的是指向key2對象的地址阅酪,無論復(fù)制多少個key2,其值始終是指向a的key2對象的內(nèi)存空間汁针。

深拷貝

有時候术辐,我們不希望父子對象之間產(chǎn)生關(guān)聯(lián),那么這時候可以用到深拷貝施无。既然屬性值類型是數(shù)組和或象時只會傳址辉词,那么我們就用以下的方法來解決這個問題,把父對象中所有屬于對象的屬性類型都遍歷賦給子對象即可猾骡。

image
  • JSON方法

    function deepCopy(o){
      return JSON.parse(JSON.stringify(o));
    }
    var a = {
      key: [1,2]
    };
    var b = deepCopy(a); //拷貝a
    b.key.push(3); //往b的key中插入新的值
    console.log(a); //1,2
    console.log(b); //1,2,3
    
  • 利用遞歸

    function deepCopy(o,c){
      var c = c || {};
      for(var i in o){
        if(typeof o[i] === 'object'){
          c[i] = (o[i].constructor === Array) ? [] : {};
          copy(o[i], c[i]);
        }else{
          c[i] = o[i];
        }
      }
      return c;
    }
    var a = {
      key: [1,2]
    };
    var b = deepCopy(a); //拷貝a
    b.key.push(3); //往b的key中插入新的值
    console.log(a); //1,2
    console.log(b); //1,2,3
    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瑞躺,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子兴想,更是在濱河造成了極大的恐慌幢哨,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嫂便,死亡現(xiàn)場離奇詭異捞镰,居然都是意外死亡,警方通過查閱死者的電腦和手機顽悼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門曼振,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蔚龙,你說我怎么就攤上這事冰评。” “怎么了木羹?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵甲雅,是天一觀的道長。 經(jīng)常有香客問我坑填,道長抛人,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任脐瑰,我火速辦了婚禮妖枚,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘苍在。我一直安慰自己绝页,他們只是感情好荠商,可當我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著续誉,像睡著了一般莱没。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上酷鸦,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天饰躲,我揣著相機與錄音,去河邊找鬼臼隔。 笑死嘹裂,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的摔握。 我是一名探鬼主播焦蘑,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼盒发!你這毒婦竟也來了例嘱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤宁舰,失蹤者是張志新(化名)和其女友劉穎拼卵,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蛮艰,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡腋腮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了壤蚜。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片即寡。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖袜刷,靈堂內(nèi)的尸體忽然破棺而出聪富,到底是詐尸還是另有隱情,我是刑警寧澤著蟹,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布墩蔓,位于F島的核電站,受9級特大地震影響萧豆,放射性物質(zhì)發(fā)生泄漏奸披。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一涮雷、第九天 我趴在偏房一處隱蔽的房頂上張望阵面。 院中可真熱鬧,春花似錦、人聲如沸样刷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽颂斜。三九已至,卻和暖如春拾枣,著一層夾襖步出監(jiān)牢的瞬間沃疮,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工梅肤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留司蔬,地道東北人。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓姨蝴,卻偏偏與公主長得像俊啼,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子左医,可洞房花燭夜當晚...
    茶點故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內(nèi)容

  • 值類型與引用類型 談淺拷貝與深拷貝之前授帕,我們需要先理清一個概念,即值類型與引用類型浮梢。 什么是值類型與引用類型跛十?這要...
    franose閱讀 616評論 1 8
  • __block和__weak修飾符的區(qū)別其實是挺明顯的:1.__block不管是ARC還是MRC模式下都可以使用,...
    LZM輪回閱讀 3,291評論 0 6
  • *面試心聲:其實這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,131評論 30 470
  • 關(guān)于構(gòu)圖奈偏,我一直有一個觀點,就是從無到有躯护,再從有到無惊来。 作者:葉明 所謂從無到有,是指每個人其實都有一個樸素的棺滞,不...
    hello85mm閱讀 220評論 0 0
  • 以卸載php為例 1唁盏、使用命令 rpm -qa|grep 列出需要卸載的軟件包 使用rpm -e 加包名
    葉天義閱讀 3,206評論 0 0