摘要:寫在最前本次嘗試通過流程圖的形式并結(jié)合兩個(gè)例子來重新理解一下中的參數(shù)傳遞。歡迎關(guān)注我的博客,不定期更新中參數(shù)到底如何傳遞借用紅寶書的一句話中所有函數(shù)的參數(shù)都是按值傳遞的這個(gè)值如果是簡(jiǎn)單類型,那么就是其本身。同時(shí)執(zhí)行第一個(gè)結(jié)果即為。
寫在最前
本次嘗試通過流程圖的形式并結(jié)合兩個(gè)例子來重新理解一下JavaScript中的參數(shù)傳遞。
歡迎關(guān)注我的博客,不定期更新中——
參數(shù)到底如何傳遞?借用紅寶書的一句話:
ECMAScript中所有函數(shù)的參數(shù)都是按值傳遞的
這個(gè)值如果是簡(jiǎn)單類型,那么就是其本身。如果是引用類型也就是對(duì)象傳遞的就是指向這個(gè)對(duì)象的地址。故我們可以認(rèn)為參數(shù)傳遞全部都是值傳遞,那么具體怎么理解呢?看下例子:
第一個(gè)例子var obj = { n: 1 }; function foo(data) { data = 2; console.log(data); //2 } foo(obj); console.log(obj.n) // 1
先不說為什么原因,我們就通過畫圖的方式來走一遍流程,我相信應(yīng)該就能理解其中的參數(shù)傳遞了。切記傳遞引用類型傳遞的是指針!
首先執(zhí)行var obj = {n: 1}; ,可以看作在棧的001地址中存入了一個(gè)指向{n:1}的指針*p
接下來為聲明function foo 此時(shí)會(huì)創(chuàng)建函數(shù)執(zhí)行上下文,產(chǎn)生一個(gè)變量對(duì)象,其中聲明了形參data,由于函數(shù)沒有執(zhí)行,當(dāng)前值為undefined。我們記data地址為022。關(guān)于更多變量對(duì)象的知識(shí)可以參考冴羽老師的這篇JavaScript深入之變量對(duì)象,本文不深入研究關(guān)于AO相關(guān),你只需要知道在聲明這個(gè)函數(shù)的時(shí)候里面的形參已經(jīng)被創(chuàng)建出來了。
執(zhí)行foo(obj) 其中會(huì)進(jìn)行參數(shù)傳遞,其中將obj中存儲(chǔ)的*p拷貝給處在022地址的data,那么此時(shí)它們就指向了同一個(gè)對(duì)象,如果某一個(gè)變量更改了n的值,另一個(gè)變量中n的值也會(huì)更改,因?yàn)槠渲斜4娴氖侵羔槨?br>
進(jìn)入函數(shù)內(nèi)部,順序執(zhí)行data = 2;此時(shí)002地址存儲(chǔ)了基本類型值,則直接存儲(chǔ)在棧中,從而與堆中的{n:1}失去了聯(lián)系。從而打印console.log(data) // 2 ,最后發(fā)現(xiàn)初始開辟的{n:1}對(duì)象沒有過更改,故而 console.log(obj.n) // 1仍然打印1。
第二個(gè)例子var obj = {n:1}; (function(obj){ console.log(obj.n); //1 obj.n=3; var obj = {n:2}; console.log(obj.n) //2 })(obj); console.log(obj.n) //3
整體來看這個(gè)例子中出現(xiàn)了同名覆蓋的問題。不太了解代碼如何執(zhí)行的流程,可能會(huì)因?yàn)橥年P(guān)系而有些混亂,不過沒關(guān)系。只要按照上一個(gè)例子的流程圖中的執(zhí)行過程,一定可以得出正確的結(jié)果。
聲明變量obj,地址為011其中存入指向{n:1}的指針*p
聲明函數(shù),雖然同為obj變量名,但是形參obj為AO中的屬性,不會(huì)與全局造成覆蓋,其擁有新的地址記作022,在未執(zhí)行前其值為undefined。
函數(shù)立即執(zhí)行,此時(shí)將全局obj賦值給形參obj,我們忽略這個(gè)重復(fù)命名的問題,其實(shí)就是將011中的 指針*p拷貝了一份給了022。同時(shí)執(zhí)行第一個(gè)console.log(obj.n)結(jié)果即為1。
執(zhí)行obj.n=3,此時(shí)為函數(shù)的形參即022中的obj來改變了對(duì)象內(nèi)n的值。
最關(guān)鍵的一步:var obj = {n:2}; 由于對(duì)象命名的關(guān)系可能很多童鞋就會(huì)有點(diǎn)懵,但依然按照同樣的方式來分析即可,由于使用了var那么就是新聲明一個(gè)對(duì)象,從而會(huì)在棧中壓入新的地址記作033,其中存入了新的指針指向了新的對(duì)象{n:2}。從而之后打印的console.log(obj.n)結(jié)果則應(yīng)是新開辟的對(duì)象中的n的值。
最后打印 console.log(obj.n) //3很顯然,全局的對(duì)象有過一次更改其值為3。
小結(jié)至此我們走完了上述兩段代碼涉及變量的所有“心路歷程”,由于作者不是科班出身,這個(gè)圖中對(duì)于堆棧以及變量重名的描述可能不是非常的準(zhǔn)確,有差錯(cuò)的地方還望不吝賜教~重點(diǎn)是能理解我希望表達(dá)的意思就好。總的來說關(guān)鍵點(diǎn)就在于傳參的過程中存在一次值的拷貝,同時(shí)如果賦值對(duì)象是引用類型傳入的是指針,明白這兩點(diǎn)之后再加上之前流程圖的分析相信再遇到類似的問題都可以有較為一致的思路了。
最后慣例po作者的博客,不定時(shí)更新中——
有問題歡迎在issues下交流。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/90603.html
摘要:繼承和前面兩篇文章中的知識(shí)非常相關(guān),如果對(duì)函數(shù)創(chuàng)建原理和原型鏈不熟悉,請(qǐng)猛戳高級(jí)程序設(shè)計(jì)筆記創(chuàng)建對(duì)象高級(jí)程序設(shè)計(jì)筆記原型圖解繼承,通俗的說,就是將自身不存在的屬性或方法,通過某種方式為自己所用文章分別介紹原型鏈繼承繼承借用構(gòu)造函數(shù)繼承組合繼 繼承和前面兩篇文章中的知識(shí)非常相關(guān),如果對(duì)函數(shù)創(chuàng)建原理和原型鏈不熟悉,請(qǐng)猛戳:《javascript高級(jí)程序設(shè)計(jì)》筆記:創(chuàng)建對(duì)象《javascri...
摘要:因此,所有在方法中定義的變量都是放在棧內(nèi)存中的當(dāng)我們?cè)诔绦蛑袆?chuàng)建一個(gè)對(duì)象時(shí),這個(gè)對(duì)象將被保存到運(yùn)行時(shí)數(shù)據(jù)區(qū)中,以便反復(fù)利用因?yàn)閷?duì)象的創(chuàng)建成本通常較大,這個(gè)運(yùn)行時(shí)數(shù)據(jù)區(qū)就是堆內(nèi)存。 上一篇:《javascript高級(jí)程序設(shè)計(jì)》筆記:繼承近幾篇博客都會(huì)圍繞著圖中的知識(shí)點(diǎn)展開 showImg(https://segmentfault.com/img/bVY0C4?w=1330&h=618);...
摘要:一棧數(shù)據(jù)結(jié)構(gòu)與不同,中并沒有嚴(yán)格意義上區(qū)分棧內(nèi)存與堆內(nèi)存。引用數(shù)據(jù)類型的值是保存在堆內(nèi)存中的對(duì)象。不允許直接訪問堆內(nèi)存中的位置,因此我們不能直接操作對(duì)象的堆內(nèi)存空間。為了更好的搞懂變量對(duì)象與堆內(nèi)存,我們可以結(jié)合以下例子與圖解進(jìn)行理解。 showImg(https://segmentfault.com/img/remote/1460000009784102?w=1240&h=683); ...
摘要:并且如果使用那么必須要指明值使用簡(jiǎn)單的數(shù)據(jù)類型不好使使用接口代理模式的注解也可以 屬于MyBatis的核心之一,這里面的坑比較多,大家多多看看吧 一 模糊查詢的三種方式介紹 我會(huì)使用resultMap處理結(jié)果集數(shù)據(jù) 1.死數(shù)據(jù)的模糊查詢 映射文件 SELECT * FROM...
摘要:緩存緩存主要是通過請(qǐng)求和響應(yīng)報(bào)文頭中的對(duì)應(yīng)信息,來控制緩存的策略。就會(huì)返回一個(gè)的狀態(tài)碼,表示可以繼續(xù)使用客戶端本地緩存的數(shù)據(jù),并刷新超時(shí)時(shí)間。與之相對(duì)的,則表示當(dāng)前響應(yīng)是針對(duì)單個(gè)用戶的,并非通用數(shù)據(jù),因此不建議任何中間緩存對(duì)其進(jìn)行緩存。 showImg(https://segmentfault.com/img/remote/1460000015383634?w=1080&h=720);...
閱讀 1893·2021-11-24 11:16
閱讀 3257·2021-09-10 10:51
閱讀 3180·2021-08-03 14:03
閱讀 1261·2019-08-29 17:03
閱讀 3238·2019-08-29 12:36
閱讀 2218·2019-08-26 14:06
閱讀 493·2019-08-23 16:32
閱讀 2661·2019-08-23 13:42