JS之函數(shù)傳參與深淺拷貝原理

很多問題看似復雜姨俩,沒有章法柬祠,事實上卻有著千絲萬縷的聯(lián)系北戏,陳道長此次闡述因為數(shù)據(jù)類型不同而引發(fā)的問題,本文主要探討JS函數(shù)參數(shù)傳遞規(guī)則漫蛔、淺拷貝嗜愈、深拷貝的原理。

變量類型和存儲

首先要明確js中變量的特點莽龟,JS變量本身沒有類型蠕嫁,只有值有類型。這句話怎么理解呢毯盈,先看下面這段代碼剃毒。

let a = 42
typeof a //'number'

注意返回的是'number',不是number搂赋,typeof檢測的不是a的類型赘阀,而是42的類型,也就是a是沒有類型的脑奠,只有a的值有類型基公。

JS總共有7種數(shù)據(jù)類型:Number、String宋欺、Boolean轰豆、Null、Symbol齿诞、Undefined酸休、Object。Object是引用類型掌挚,其他的是基本類型雨席。至于數(shù)組和函數(shù)屬于Object的子類型。不過typeof 一個函數(shù)的時候 會返回'function'吠式,這是為了彰顯函數(shù)是一等公民的地位。它要特殊一點抽米。

我們在聲明一個變量時特占,會給變量進行賦值,變量在存儲的時候也有區(qū)別云茸。基本類型值存放在棧中是目,可以直接訪問。引用類型值存放在堆內(nèi)存中标捺。很關(guān)鍵的一點:JS是不允許直接訪問內(nèi)存的懊纳,所以當一個變量的值是Object時揉抵,它保存的只是一個指針,指向的是Object存放的內(nèi)存地址嗤疯。

定義一個var a = {{類型值}};b = a冤今,會出現(xiàn)下面兩種情況:1、當類型值是基本類型時茂缚,a和b值雖然相同戏罢,但確是兩個獨立的變量。2脚囊、當類型值是Object時龟糕,a和b存儲的是一樣的指針,指向了共同的地址悔耘。所以再修改a或者b時讲岁,1會有各自的變化,2會兩個變化完還是一樣衬以。

JS函數(shù)參數(shù)

事實上缓艳,參數(shù)傳遞就是受到數(shù)據(jù)類型的影響。JS的函數(shù)有幾個特性:1泄鹏、參數(shù)沒有個數(shù)限制郎任,不管你函數(shù)里要用幾個,它卻可以接收任意多個备籽,因為不用它操心舶治,來的這么些參數(shù)都放到了一個參數(shù)數(shù)組里。另外參數(shù)值也沒有類型限制车猬,非常的開放霉猛,然后函數(shù)內(nèi)再通過arguments對象去訪問這個數(shù)組,拿到參數(shù)珠闰,所以參數(shù)不跟函數(shù)直接打交道惜浅,就好比中間有個傳話的。所以這也是為什么es6之前中不能直接給函數(shù)參數(shù)指定默認值伏嗜。

es6新搞了個rest參數(shù)坛悉,它搭配了一個數(shù)組,變量多余的參數(shù)會存放到這個數(shù)組里承绸,就不用arguments對象來獲取了裸影。

// arguments變量的寫法
function sortNumbers() {
  return Array.prototype.slice.call(arguments).sort();
}

// rest參數(shù)的寫法
const sortNumbers = (...numbers) => numbers.sort();

參數(shù)傳遞問題

重點來了!函數(shù)參數(shù)傳遞其實就是把函數(shù)外的值復制給函數(shù)內(nèi)部的值军熏,也就是按照上面的規(guī)則來
參數(shù)來自外部轩猩,要傳遞到函數(shù)里,找個中間變量,JS是參數(shù)是按“值”傳遞的均践,這個“值”就是變量的值晤锹。當變量的值屬于基本類型,這個“值”就是普通值彤委,當變量的值是引用類型時鞭铆,這個“值”時引用類型的地址。
傳遞的參數(shù)值是基本類型值會復制給一個局部變量葫慎。傳遞的參數(shù)是引用類型的值衔彻,復制的是地址。

深淺拷貝

為啥存在淺拷貝和深拷貝偷办,原因和上面一樣艰额。當我們想把對象a賦值給變量b,你會發(fā)現(xiàn)b和a指向的是一個地方椒涯。b改變的時候a也會變柄沮。這就是因為變量存儲的只是個指針,引用類型的值是放在內(nèi)存中废岂,沒法直接訪問祖搓。

普通復制就是淺拷貝,新對象修改時湖苞,老對象也會發(fā)生變化拯欧。
但是我們想把b復制給a后,然后兩個對象互不干擾财骨,完成這樣的復制镐作,這就是深拷貝。

深拷貝的原理就是把a對象的每個屬性的值遍歷一遍隆箩,然后把它復制給一個中間值该贾,它作為普通的值進行復制到b對象的屬性。這就回到了基本變量的復制問題捌臊。

當然一個對象的屬性也可能是對象杨蛋,例如:obj = [{a:1},{b:2}],我們想把obj賦值給新對象理澎,這個時候就得遞歸遍歷了逞力,把對象中a屬性的值1和b屬性的值2都給取到,然后把1和2再復制到新的對象里去糠爬,這個時候新對象就不會影響到之前的對象了掏击。

說的有點繞,就是要切斷新對象和老對象的關(guān)系秩铆,但是咱們又沒辦法直接操作內(nèi)存,就只能通過引用取到老對象中存的數(shù)據(jù)值,拿出來之后放到新對象里殴玛。這就是深拷貝的思想捅膘。

總結(jié)

由于js中數(shù)據(jù)類型不同,變量保存的值也有兩種存儲方式滚粟,在堆里面和在棧面寻仗,存儲方式不同,也就導致了讀取方式不同凡壤,也就導致了復制操作的結(jié)果不同署尤,而參數(shù)傳遞和深淺拷貝都是數(shù)據(jù)復制的操作。所以兩者受到的約束也是相同的亚侠,也就要遵循變量讀取的規(guī)則曹体。

本文是陳少棠原創(chuàng),收錄在《齊云札記》硝烂,轉(zhuǎn)載請標明原作箕别。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市滞谢,隨后出現(xiàn)的幾起案子串稀,更是在濱河造成了極大的恐慌,老刑警劉巖狮杨,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件母截,死亡現(xiàn)場離奇詭異,居然都是意外死亡橄教,警方通過查閱死者的電腦和手機清寇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來颤陶,“玉大人颗管,你說我怎么就攤上這事∽易撸” “怎么了垦江?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長搅方。 經(jīng)常有香客問我比吭,道長,這世上最難降的妖魔是什么姨涡? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任衩藤,我火速辦了婚禮,結(jié)果婚禮上涛漂,老公的妹妹穿的比我還像新娘赏表。我一直安慰自己检诗,他們只是感情好,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布瓢剿。 她就那樣靜靜地躺著逢慌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪间狂。 梳的紋絲不亂的頭發(fā)上攻泼,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機與錄音鉴象,去河邊找鬼忙菠。 笑死,一個胖子當著我的面吹牛纺弊,可吹牛的內(nèi)容都是我干的牛欢。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼俭尖,長吁一口氣:“原來是場噩夢啊……” “哼氢惋!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起稽犁,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤焰望,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后已亥,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體熊赖,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年虑椎,在試婚紗的時候發(fā)現(xiàn)自己被綠了震鹉。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡捆姜,死狀恐怖传趾,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情泥技,我是刑警寧澤浆兰,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站珊豹,受9級特大地震影響簸呈,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜店茶,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一蜕便、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧贩幻,春花似錦轿腺、人聲如沸两嘴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽溶诞。三九已至,卻和暖如春决侈,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背喧务。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工赖歌, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人功茴。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓庐冯,卻偏偏與公主長得像,于是被迫代替她去往敵國和親坎穿。 傳聞我的和親對象是個殘疾皇子展父,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

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

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,103評論 1 32
  • 函數(shù)和對象 1、函數(shù) 1.1 函數(shù)概述 函數(shù)對于任何一門語言來說都是核心的概念玲昧。通過函數(shù)可以封裝任意多條語句栖茉,而且...
    道無虛閱讀 4,566評論 0 5
  • 這是16年5月份編輯的一份比較雜亂適合自己觀看的學習記錄文檔,今天18年5月份再次想寫文章孵延,發(fā)現(xiàn)簡書還為我保存起的...
    Jenaral閱讀 2,762評論 2 9
  • 人都是孤獨的 孤獨的時候總想找些東西填滿內(nèi)心的空虛 孤孤單單的靈魂 內(nèi)心爆棚的欲望 堵的人喘不過氣來 刷了半天手機...
    tq_閱讀 190評論 0 0
  • Given a singly linked list, group all odd nodes together ...
    極速魔法閱讀 219評論 0 0