深拷貝/淺拷貝

深淺拷貝

數(shù)據(jù)類型及特點(diǎn)

  • 基本數(shù)據(jù)類型
    Undefined, Null, Symbol, Boolean, String, Number
    特點(diǎn):直接存儲(chǔ)在棧中的數(shù)據(jù)
  • 對(duì)象數(shù)據(jù)類型(引用數(shù)據(jù)類型)
    特點(diǎn):棧中存儲(chǔ)的是對(duì)該對(duì)象的引用囱挑,真實(shí)的數(shù)據(jù)存儲(chǔ)在堆內(nèi)存中

引用數(shù)據(jù)類型在棧中存儲(chǔ)了指針谬俄,該指針指向堆中的該實(shí)體的起始地址酪呻,當(dāng)解釋器尋找引用值時(shí),
會(huì)首先檢索其在棧中的地址鸯绿,取得地址后從堆中獲得實(shí)體

深淺拷貝

深淺拷貝只針對(duì)Object或者Array這樣的引用數(shù)據(jù)類型

淺拷貝只復(fù)制指向?qū)ο蟮闹羔樀刂吩侣澹皇菑?fù)制對(duì)象本身日麸,新舊對(duì)象還是共享同一塊內(nèi)存杭煎。
深拷貝會(huì)創(chuàng)造另外一個(gè)一摸一樣的對(duì)象,新舊對(duì)象不共用同一塊內(nèi)存背率,修改新對(duì)象不會(huì)影響到舊對(duì)象话瞧。

淺拷貝與賦值的區(qū)別

var obj1 = {name: 'LiLy', age: '12', language: ['english', 'chinese', 'frech']}
  • 賦值: 賦的是該對(duì)象在棧中的地址,而不是堆中的數(shù)據(jù)寝姿。
    兩個(gè)對(duì)象指向的是同個(gè)存儲(chǔ)空間交排,無(wú)論哪個(gè)對(duì)象發(fā)生改變,其實(shí)改變的都是原對(duì)象会油,是聯(lián)動(dòng)的个粱。

          var obj2 = obj1
          obj2.name = 'Lucy'
          obj2.language[0] = 'India'
          
          obj1 和 obj2 都是
          
          {
              age: "12"
              language: (3) ["India", "chinese", "frech"]
              name: "Lucy"
           }
    
  • 淺拷貝:按位拷貝對(duì)象古毛,它會(huì)創(chuàng)建一個(gè)對(duì)象翻翩,這個(gè)對(duì)象有著原始對(duì)象屬性值的一份精確拷貝。
    如果屬性是基本數(shù)據(jù)類型稻薇,拷貝的就是基本類型的值嫂冻;
    如果屬性是引用數(shù)據(jù)類型,拷貝的就是內(nèi)存地址塞椎。
    因此如果其中一個(gè)對(duì)象改變了這個(gè)內(nèi)存地址桨仿,就會(huì)影響到另一個(gè)對(duì)象

function shallowCopy(src) {
    var dst = {}
    for (var prop in src) {
        if (src.hasOwnProperty(prop)) {
            dst[prop] = src[prop]
        }
    }
    return dst
}

var obj3 = shallowCopy(obj1)

obj3.name = 'Bob'
obj3.language[0] = 'lan3'

obj3: {
      age: "12"
      language: (3) ["lan3", "chinese", "frech"]
      name: "Bob"
}

obj1: {
    age: "12"
    language: (3) ["lan3", "chinese", "frech"]
    name: "Lucy"
}

總結(jié):

-- 和原數(shù)據(jù)是否指向同個(gè)對(duì)象 第一層數(shù)據(jù)為基本數(shù)據(jù)類型 元數(shù)據(jù)中包含子對(duì)象
賦值 改變會(huì)使原數(shù)據(jù)一同改變 改變會(huì)使原數(shù)據(jù)一同改變
淺拷貝 改變不會(huì)使原數(shù)據(jù)一同改變 改變會(huì)使原數(shù)據(jù)一同改變
深拷貝 改變不會(huì)使原數(shù)據(jù)一同改變 改變不會(huì)使原數(shù)據(jù)一同改變

淺拷貝實(shí)現(xiàn)方式

  1. Object.assign()

把任意多個(gè)源對(duì)象的可枚舉屬性,拷貝給目標(biāo)對(duì)象案狠,然后返回目標(biāo)對(duì)象服傍。其中拷貝的是對(duì)象屬性的引用,而不是對(duì)象屬性身骂铁。

var obj1= {
    age: "12",
    language: (3) [1, 2, 3],
    name: "a",
    love: {son: 'tom'}
};
        
var obj2=Object.assign({}, obj1);  // obj2: {age: "12", language: undefined, name: "a",love: {son: "tom"}}

obj2.love.son='Bob';              // obj2: {age: "12", language: undefined, name: "a",love: {son: "Bob"}}, obj1: {age: "12", language: undefined, name: "a",love: {son: "Bob"}}

// 當(dāng)object 只有一層的時(shí)候吹零,是深拷貝
obj2.age='13'                   // obj2: {age: "13", language: undefined, name: "a"}, obj1: {age: "12", language: undefined, name: "a"}
  1. Array.prototype.concat()

修改新對(duì)象的子對(duì)象會(huì)改到原對(duì)象

var arr1=[1,2,{name: 'a1'}];
var arr2=arr1.concat();  // arr2: [1,2,{name: 'a1'}]
arr2[1] = 3;             // arr1:[1,2,{name: 'a1'}], arr2: [1,3,{name: 'a1'}]
arr2[2].name='a2';       // arr1:[1,2,{name: 'a2'}], arr2: [1,3,{name: 'a2'}]
  1. Array.prototype.slice()

修改新對(duì)象的子對(duì)象會(huì)改到原對(duì)象

var arr1=[1,2,{name: 'a1'}];
var arr2=arr1.slice();  // arr2: [1,2,{name: 'a1'}]
arr2[1] = 3;             // arr1:[1,2,{name: 'a1'}], arr2: [1,3,{name: 'a1'}]
arr2[2].name='a2';       // arr1:[1,2,{name: 'a2'}], arr2: [1,3,{name: 'a2'}]     

深拷貝實(shí)現(xiàn)方式

  1. JSON.parse(JSON.stringfy())
    先轉(zhuǎn)換成JSON字符串再轉(zhuǎn)成JSON對(duì)象,會(huì)產(chǎn)生新的對(duì)象拉庵,而且對(duì)象會(huì)開辟新的棧灿椅,實(shí)現(xiàn)深拷貝。

注意: 不能處理函數(shù),因?yàn)镴SON.stringfy()不能結(jié)束函數(shù)茫蛹,轉(zhuǎn)化結(jié)果為null

var arr = [1, 3, {
    username: ' kobe'
}];

var arr4 = JSON.parse(JSON.stringify(arr));

arr4[2].username = 'duncan';   // arr4:[1, 3, {username: 'duncan'}], arr: [1, 3, {username: 'kobe'}]

arr4[1]=2;                    // arr4:[1, 2, {username: 'duncan'}], arr: [1, 3, {username: 'kobe'}]
  1. 函數(shù)庫(kù)lodash

_.cloneDeep函數(shù)實(shí)現(xiàn)深拷貝

var obj1={a: 's', {name: 'Lily'}};

var obj2 = _.cloneDeep(obj1); 
  1. 手寫遞歸方法

遍歷對(duì)象操刀,數(shù)組,直到里面都是基本數(shù)據(jù)類型婴洼,再進(jìn)行復(fù)制

function checkedType (target) {
    return Object.prototype.toString.call(target).slice(8, -1)
}

function clone (target) {
    // result 為最后返回的結(jié)果骨坑, tartgetType為目標(biāo)數(shù)據(jù)類型
    let result, tartgetType = checkedType(target)
    
    if (tartgetType === 'Array') {
        result = []
    } else if (tartgetType === 'Object') {
       result = {}
   } else {
       // 基本數(shù)據(jù)類型,直接返回結(jié)果
        return target
   }
   
    for (var key in target) {
        // 遍歷對(duì)象或數(shù)組窃蹋,直到找到基本數(shù)據(jù)類型進(jìn)行復(fù)制
        let value = target[key]
        if (checkedType(value) === 'Object' || checkedType(value) === 'Array') {
             //繼續(xù)遍歷獲取到value值
              result[i] = clone(value)
        } else {
            result[i] = value
        }
    }
    return result
}    
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末卡啰,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子警没,更是在濱河造成了極大的恐慌匈辱,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件杀迹,死亡現(xiàn)場(chǎng)離奇詭異亡脸,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)树酪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門浅碾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人续语,你說(shuō)我怎么就攤上這事垂谢。” “怎么了疮茄?”我有些...
    開封第一講書人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵滥朱,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我力试,道長(zhǎng)徙邻,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任畸裳,我火速辦了婚禮缰犁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘怖糊。我一直安慰自己帅容,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開白布伍伤。 她就那樣靜靜地躺著并徘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪嚷缭。 梳的紋絲不亂的頭發(fā)上饮亏,一...
    開封第一講書人閱讀 51,679評(píng)論 1 305
  • 那天耍贾,我揣著相機(jī)與錄音,去河邊找鬼路幸。 笑死荐开,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的简肴。 我是一名探鬼主播晃听,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼砰识!你這毒婦竟也來(lái)了能扒?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤辫狼,失蹤者是張志新(化名)和其女友劉穎初斑,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體膨处,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡见秤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了真椿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鹃答。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖突硝,靈堂內(nèi)的尸體忽然破棺而出测摔,到底是詐尸還是另有隱情,我是刑警寧澤解恰,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布锋八,位于F島的核電站,受9級(jí)特大地震影響修噪,放射性物質(zhì)發(fā)生泄漏查库。R本人自食惡果不足惜路媚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一黄琼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧整慎,春花似錦脏款、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至拧揽,卻和暖如春剃盾,著一層夾襖步出監(jiān)牢的瞬間腺占,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工痒谴, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留衰伯,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓积蔚,卻偏偏與公主長(zhǎng)得像意鲸,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子尽爆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355