JavaScript深淺拷貝

原文鏈接 http://blog.poetries.top/2018/12/21/js-deep-copy/

關(guān)注公眾號(hào)獲取更多資訊

一、前言

js中妖啥,變量的類型可以大致分成兩種:基本數(shù)據(jù)類型和引用數(shù)據(jù)類型,其中基本數(shù)據(jù)類型指的是簡單的數(shù)據(jù)段,包括:

  • undefined
  • Null
  • Boolean
  • Number
  • String(字符串在一些其他語言中是被當(dāng)做對(duì)象使用的,屬于引用類型俱笛,但在js里是基本類型)

而引用類型的值指的是可能包含多個(gè)值的對(duì)象。本質(zhì)上传趾,是因?yàn)榛緮?shù)據(jù)類型保存在棧內(nèi)存,而引用類型保存在堆內(nèi)存中迎膜。為什么要分兩種保存方式呢? 根本原因在于保存在棧內(nèi)存的必須是大小固定的數(shù)據(jù)浆兰,引用類型的大小不固定磕仅,只能保存在堆內(nèi)存中,但是我們可以把它的地址寫在占內(nèi)存中以供我們訪問

var a = 1;//定義了一個(gè)number類型
var obj1 = {//定義了一個(gè)objr類型
    name:'obj'
};

在執(zhí)行這段代碼后簸呈,內(nèi)存空間里是這樣的

image.png

因?yàn)檫@種保存方式的存在榕订,所以我們在操作變量的時(shí)候,如果是基本數(shù)據(jù)類型蜕便,則按值訪問劫恒,操作的就是變量保存的值;如果是引用類型的值轿腺,我們只是通過保存在變量中的引用類型的地址類操作實(shí)際對(duì)象两嘴。從而也引出了所謂的深淺復(fù)制問題

二、淺拷貝

方法一

// 假設(shè)有兩個(gè)對(duì)象

var objA = {
  a: 'aa',
  b: 'bb'
};
var objB = {};
// 現(xiàn)在想把對(duì)象A的值復(fù)制給B吃溅,由于對(duì)象A的兩個(gè)值都是原始類型溶诞,用淺復(fù)制即可

function copy(sub, sup) {
  for (var key in sup) {
    sub[key] = sup[key];
  }
}
copy(objB, objA);

方法二

Object.assign() (兼容性不好)

方法三

_.clone()

方法四

數(shù)組中concatslice方法

方法五

ES6展開運(yùn)算

var arr = [{name:'poetries',age:22}]

var target = [...arr]

三、深拷貝

簡單來說深復(fù)制就是當(dāng)遇到值是對(duì)象類型的時(shí)候就再運(yùn)行一遍復(fù)制

方法一 JSON.parse(JSON.stringify(obj))

簡單粗暴又有點(diǎn)dirty决侈,但是能滿足日常需求螺垢,只能處理json能理解的數(shù)據(jù)格式,當(dāng)然不包括函數(shù)了赖歌,性能也沒有特別好

方法二 lodash —— _.cloneDeep()

很好地兼容了ES6的新引用類型枉圃,而且處理了環(huán)型對(duì)象的情況

方法三 jQuery —— .clone() /.extend()

源碼適合初學(xué)者學(xué)習(xí),比較好理解

方法四 自己實(shí)現(xiàn)一個(gè)

function deepCopy (obj) {
    var result;

    //引用類型分?jǐn)?shù)組和對(duì)象分別遞歸
    if (Object.prototype.toString.call(obj) == '[object Array]') {
      result = []
      for (i = 0; i < obj.length; i++) {
        result[i] = deepCopy(obj[i])
      }
    } else if (Object.prototype.toString.call(obj) == '[object Object]') {
      result = {}
      for (var attr in obj) {
        result[attr] = deepCopy(obj[attr])
      }
    }
    //值類型直接返回
    else {
      return obj
    }
    return result
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末庐冯,一起剝皮案震驚了整個(gè)濱河市孽亲,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌展父,老刑警劉巖返劲,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異栖茉,居然都是意外死亡篮绿,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門吕漂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來亲配,“玉大人,你說我怎么就攤上這事『鸹ⅲ” “怎么了犬钢?”我有些...
    開封第一講書人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長思灰。 經(jīng)常有香客問我玷犹,道長,這世上最難降的妖魔是什么官辈? 我笑而不...
    開封第一講書人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任箱舞,我火速辦了婚禮,結(jié)果婚禮上拳亿,老公的妹妹穿的比我還像新娘晴股。我一直安慰自己,他們只是感情好肺魁,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開白布电湘。 她就那樣靜靜地躺著,像睡著了一般鹅经。 火紅的嫁衣襯著肌膚如雪寂呛。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,262評(píng)論 1 308
  • 那天瘾晃,我揣著相機(jī)與錄音贷痪,去河邊找鬼。 笑死蹦误,一個(gè)胖子當(dāng)著我的面吹牛劫拢,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播强胰,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼舱沧,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了偶洋?” 一聲冷哼從身側(cè)響起熟吏,我...
    開封第一講書人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎玄窝,沒想到半個(gè)月后牵寺,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡恩脂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年缸剪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片东亦。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出典阵,到底是詐尸還是另有隱情奋渔,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布壮啊,位于F島的核電站嫉鲸,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏歹啼。R本人自食惡果不足惜玄渗,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望狸眼。 院中可真熱鬧藤树,春花似錦、人聲如沸拓萌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽微王。三九已至屡限,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間炕倘,已是汗流浹背钧大。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留罩旋,地道東北人啊央。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像瘸恼,于是被迫代替她去往敵國和親劣挫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

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

  • underscore 的源碼中东帅,有很多地方用到了 Array.prototype.slice() 方法压固,但是并沒有...
    theCoder閱讀 601評(píng)論 0 1
  • 簡單講呢,深淺拷貝靠闭,都是進(jìn)行復(fù)制帐我,那么區(qū)別主要在于復(fù)制出來的新對(duì)象和原來的對(duì)象是否會(huì)互相影響,改一個(gè)愧膀,另一個(gè)也會(huì)變...
    _千尋瀑_閱讀 253評(píng)論 0 2
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,111評(píng)論 1 32
  • Javascript有六種基本數(shù)據(jù)類型(也就是簡單數(shù)據(jù)類型)拦键,它們分別是:Undefined,Null檩淋,Boole...
    XMUBeike閱讀 301評(píng)論 0 0
  • 心里有了疑問芬为, 便會(huì)經(jīng)常想起萄金。 當(dāng)我每次把這疑問向父母問起, 他們都會(huì)大聲訓(xùn)斥我媚朦, 讓我不要再有這種愚蠢的想法氧敢; ...
    空空丨如然閱讀 145評(píng)論 0 0