關于深淺拷貝的原理及實現(xiàn)(超級萌新版)

寫一下這幾天在看面試題時又回顧到的一個知識點借卧,深淺拷貝。

這個應該是在ES5面向?qū)ο笾皩戇^敦姻,現(xiàn)在是忘的差不多了瘾境,在梳理了一下邏輯以后,決定重新開篇文章寫一下镰惦。

一迷守、堆與棧

如果是明白堆與棧的,或者是不屑于理解基礎知識旺入,只求深淺拷貝怎么寫的兑凿,可以跳過這部分直接看后面。但我認為理解一個東西茵瘾,就要貫徹到底礼华,一知半解多半會出問題。

那我們先說一下堆與棧拗秘,什么是堆什么是棧呢圣絮。在我們創(chuàng)建變量之初,內(nèi)存會開辟兩類空間雕旨,就是棧和堆扮匠。當然我們知道捧请,變量有兩種類型:基本數(shù)據(jù)類型(包括ES6的symbol數(shù)據(jù))和引用類型數(shù)據(jù),所以這兩種對象分別儲存于這兩個空間之中棒搜。

這樣應該很好理解疹蛉,那么堆與棧的關系呢?這里就要提到一個問題了力麸,在ECMAscript語法中可款,js是不允許直接訪問堆內(nèi)存的,那么我們要如何取出引用類數(shù)據(jù)呢末盔,這就要提到地址了筑舅。每個引用類數(shù)據(jù)座慰,都有對應的地址(地址不唯一)陨舱,每個地址都能指向?qū)亩褦?shù)據(jù)。舉個例子:

let demo = {id:"xiaoming"}

那么這行代碼中版仔,{id:"xiaoming"}就會儲存于內(nèi)存開辟的堆空間中游盲,而demo就會作為地址的變量名存放于棧內(nèi)存中。如果還沒看懂蛮粮,我畫個圖益缎,作為對比我再新建幾個變量:

let demo = {id:"xiaoming"};

let a = 'hello';

let b = 123

湊合著看吧然想。莺奔。

通過上述圖示,應該就能很清楚的展示基本數(shù)據(jù)類型和引用數(shù)據(jù)類型的存儲區(qū)別了变泄,這里再附上一段比較代碼令哟,大家參考一下,應該會更加清楚:

var str1 = new String('abc');

var str2='abc';

alert(str1==str2);// true

alert(str1===str2);// false

最后總結一下:
1.在代碼運行的時候妨蛹,每個線程會分配一個堆和一個棧屏富。堆的大小是不固定的,可以隨時增加蛙卤;而棧創(chuàng)建的時候就確定大小狠半,所以可能溢出。

2.堆的空間大颤难,但是運行效率相對較低神年;而棧相反。

3.棧存放基本類型數(shù)據(jù)行嗤,函數(shù)已日,對象指針等;堆存放對象昂验;

二捂敌、遞歸

同上艾扮,只想看深淺拷貝代碼的可以跳過了。但這里我還是建議看一下的占婉。

簡單來說泡嘴,遞歸是一種函數(shù)編碼思想。用法就是在函數(shù)內(nèi)調(diào)用自身逆济,同時為其中增加一個條件來終止代碼(不然會無限循環(huán))酌予。舉個例子:

var num = 0;

? ? ? ? function foo2(){

? ? ? ? ? ? num ++

? ? ? ? ? ? console.log("當前的num值:"+num);

? ? ? ? ? ? if(num > 5){

? ? ? ? ? ? ? ? // 終止代碼的執(zhí)行

? ? ? ? ? ? ? ? return ;

? ? ? ? ? ? }

? ? ? ? ? ? foo2();

? ? ? ? }

? ? ? ? foo2();

遞歸是一種理解起來并不難,但實際操作時卻需要想半天的東西奖慌,只能多寫來提高熟練度了抛虫。

三、淺拷貝

所謂拷貝简僧,說穿了就是數(shù)據(jù)的復制建椰,但在js中因為我前面提到的堆和棧的問題,我們?nèi)绻皇呛唵蔚难h(huán)岛马,僅僅只能對淺層的數(shù)據(jù)進行復制棉姐,這就是淺拷貝,那么在不涉及嵌套對象的前提下啦逆,就對僅僅是基本數(shù)據(jù)類型的對象進行拷貝伞矩。

懶人版淺拷貝方法一

此方法是ES6中提供的,但注意夏志,該方法不會拷貝不可枚舉的屬性和繼承屬性乃坤。

object.assign

?let demo = {};

? ? ? ? let test = {

? ? ? ? ? ? name:'aaa',

? ? ? ? ? ? age:123

? ? ? ? }

? ? ? ? Object.assign(demo,test);

? ? ? ? console.log(demo);

這里多一嘴:這種方式不止ES6,在jq中也有提供$.extend()方法沟蔑,效果是一樣的湿诊。

懶人版淺拷貝方法二

同樣是在ES6中,由語法糖提供的擴展運算符溉贿,這個就更簡單了枫吧。。

demo = {...test}

console.log(demo);

懶人版淺拷貝方法三

看了上面的宇色,覺得淺拷貝真的很簡單吧九杂,這里再說一下,同樣可以用slice宣蠕,concat等對數(shù)組進行操作(注意splice方法例隆,該方法會對原數(shù)組進行切剪)

js原生代碼的淺拷貝

function simpleCopy(data) {

? ? ? ? ? ? // 新地址, 判斷data是數(shù)組,還是對象

? ? ? ? ? ? var newData = Array.isArray(data)? [] : {}

? ? ? ? ? ? // 循環(huán)data ,然后復制數(shù)據(jù)

? ? ? ? ? ? for(var key in data){

? ? ? ? ? ? ? ? // 復制

? ? ? ? ? ? ? ? newData[key] = data[key]

? ? ? ? ? ? }

? ? ? ? ? ? // 返回復制完成的數(shù)據(jù)集合

? ? ? ? ? ? return newData;

? ? ? ? }


四抢蚀、深拷貝

終于到深拷貝了镀层,那么先說一下,深拷貝就不止是對淺層數(shù)據(jù)的拷貝了唱逢,我們要結合上面的堆棧和遞歸思想吴侦,實現(xiàn)原有對象的完全復制。二者實現(xiàn)真正的分離坞古。

懶人版深拷貝方法一

ok备韧,那么按照順序先放一個懶人版的,我們可以通過JSON來實現(xiàn)深淺拷貝(應該是目前最簡單的深淺拷貝了)痪枫。

又不能粘貼了织堂。。

遞歸深拷貝

簡單版

這里提出三個問題奶陈,有待解決:

1.關于不可枚舉的屬性以及symbol類型數(shù)據(jù)的復制

2.Date易阳,RegExp類型

3.關于數(shù)據(jù)循環(huán)引用的問題?

我寫了一段吃粒,但是沒有完全解決潦俺,帶我搞定了上傳代碼

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市声搁,隨后出現(xiàn)的幾起案子黑竞,更是在濱河造成了極大的恐慌,老刑警劉巖疏旨,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異扎酷,居然都是意外死亡檐涝,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進店門法挨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來谁榜,“玉大人,你說我怎么就攤上這事凡纳∏灾玻” “怎么了?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵荐糜,是天一觀的道長巷怜。 經(jīng)常有香客問我,道長暴氏,這世上最難降的妖魔是什么延塑? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮答渔,結果婚禮上关带,老公的妹妹穿的比我還像新娘。我一直安慰自己沼撕,他們只是感情好宋雏,可當我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布芜飘。 她就那樣靜靜地躺著,像睡著了一般磨总。 火紅的嫁衣襯著肌膚如雪燃箭。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天舍败,我揣著相機與錄音招狸,去河邊找鬼。 笑死邻薯,一個胖子當著我的面吹牛裙戏,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播厕诡,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼累榜,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了灵嫌?” 一聲冷哼從身側(cè)響起壹罚,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎寿羞,沒想到半個月后猖凛,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡绪穆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年辨泳,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片玖院。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡菠红,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出难菌,到底是詐尸還是另有隱情试溯,我是刑警寧澤,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布郊酒,位于F島的核電站遇绞,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏猎塞。R本人自食惡果不足惜试读,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望荠耽。 院中可真熱鬧钩骇,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至纽匙,卻和暖如春务蝠,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背烛缔。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工螟深, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留拣帽,地道東北人驶赏。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓痰驱,卻偏偏與公主長得像,于是被迫代替她去往敵國和親晕翠。 傳聞我的和親對象是個殘疾皇子喷舀,可洞房花燭夜當晚...
    茶點故事閱讀 42,834評論 2 345

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