javascript的變量、傳值、傳址、參數(shù)之間關(guān)系
先把收獲晾一下:
1.javascrip變量包含兩種類型的值,一種為引用類型的值,一種是基本類型的值。引用類型包括:Array,Object,F(xiàn)unction(可以這么理解,非基本類型的都是引用類型);5種基本類型包括:undefined,null,string,boolean,number
2.函數(shù)的參數(shù)的傳遞的機(jī)制是復(fù)制變量值。
書上說:”把函數(shù)外部的值復(fù)制給函數(shù)內(nèi)部的參數(shù),就和把值從一個(gè)變量復(fù)制給另一個(gè)變量一樣。基本類型的傳遞如同基本類型變量的復(fù)制一樣,而引用類型的則如同引用類型變量的復(fù)制一樣?!?nbsp;
”當(dāng)一個(gè)變量復(fù)制引用類型的值時(shí),同樣也會(huì)將存儲(chǔ)在變量對(duì)象中的值復(fù)制一份放到為新變量分配的空間中。不同的是這個(gè)值的副本實(shí)際上是一個(gè)指針,而這個(gè)指針指向存儲(chǔ)在堆中的一個(gè)對(duì)象。復(fù)制操作結(jié)束后,兩個(gè)變量實(shí)際上將引用同一個(gè)對(duì)象。因此改變其中一個(gè)變量,就會(huì)影響到另一個(gè)變量?!?/p>
【注意:復(fù)制引用類型的值,才是傳址】
3.參數(shù)實(shí)際上是函數(shù)的局部變量。
----------------------------------------------------------------------------
基本概念的解釋:
傳值:把A的數(shù)值傳到B,改變B,A不會(huì)跟著變,B存的是跟A一樣的值;
傳址:把A的地址傳到B,改變B,A同時(shí)跟著變,B存的只是A的地址(類似電腦的快捷方式)。
一個(gè)具有值類型(value type)的數(shù)據(jù)存放在棧內(nèi)的一個(gè)變量中。即是在棧中分配內(nèi)存空間,直接存儲(chǔ)所包含的值,其值就代表數(shù)據(jù)本身。值類型的數(shù)據(jù)具有較快的存取速度。
一個(gè)具有引用類型(reference type)的數(shù)據(jù)并不駐留在棧中,而是存儲(chǔ)于堆中。即是在堆中分配內(nèi)存空間,不直接存儲(chǔ)所包含的值,而是指向所要存儲(chǔ)的值,其值代表的是所指向的地址。當(dāng)訪問一個(gè)具有引用類型的數(shù)據(jù)時(shí),需要到棧中檢查變量的內(nèi)容,該變量引用堆中的一個(gè)實(shí)際數(shù)據(jù)。引用類型的數(shù)據(jù)比值類型的數(shù)據(jù)具有更大的存儲(chǔ)規(guī)模和較低的訪問速度。
----------------------------------------------------------------------------
下面是三個(gè)問題。
【問題1】:為什么change(a)函數(shù)執(zhí)行完之后,外面的a沒有受干擾呢?
<script> var a = [1, 2, 3]; function change(a) { console.log(a);//[1,2,3] a = 2; //傳值 console.log(a);//2 } change(a); console.log(a); //[1,2,3] </script>
問題1解答:因?yàn)閏hange(a)的執(zhí)行過程是這樣的,首先將對(duì)象a(數(shù)組)傳入到change以后,被復(fù)制給change的參數(shù)a。而后a=2是一個(gè)賦值語(yǔ)句,變成傳值。此時(shí)a=2是值類型,并不涉及引用地址的問題。所以并沒有影響外部的a。
【問題2】:為什么change(a)函數(shù)執(zhí)行完之后,外面的a受到干擾呢?
<script> var a = [1, 2, 3]; function change() { a = 2;//傳值 } change(); console.log(a); //2 </script>
問題2解答:當(dāng)執(zhí)行change()的時(shí)候,函數(shù)在自己的執(zhí)行環(huán)境中找尋作用域鏈,活動(dòng)對(duì)象(activation object)并不包含變量a,于是沿著作用域鏈向上找,找到全局執(zhí)行環(huán)境,發(fā)現(xiàn)變量a,于是此時(shí)函數(shù)內(nèi)部的a和外部a在內(nèi)存上是同一個(gè)地址,自然函數(shù)內(nèi)部a變了,外部也會(huì)跟著變。
解析:?jiǎn)栴}2和問題1的區(qū)別在于,問題2并沒有引入?yún)?shù),所以不涉及復(fù)制變量的事情。
【問題3】:為什么change(a)函數(shù)執(zhí)行完之后,外面的a受到干擾呢?
<script> var a = [1, 2, 3]; function change(b) { b[0] = 2; } change(a); console.log(a); //[2,2,3] </script>
問題3解答:這個(gè)和問題1非常類似,唯獨(dú)不一樣的就是a=2,換成了b[0]=2,我一開始也很疑惑,不說復(fù)制嗎?參數(shù)b應(yīng)該是個(gè)復(fù)制值,怎么會(huì)影響到外面的a呢?
的確,change函數(shù)執(zhí)行時(shí),參數(shù)b是a的復(fù)制值。因?yàn)閍是引用類型,所以在函數(shù)內(nèi)部是b和a按引用來訪問的是一個(gè)地址的對(duì)象。b[0]=2的出現(xiàn),并不影響在函數(shù)內(nèi)部b和a引用的是同一個(gè)對(duì)象。
【問題4】:為什么change(a)函數(shù)執(zhí)行完之后,外面的a沒有受到干擾呢?
var a = [1, 2, 3]; function change(b) { console.log(b);//[1,2,3] b=2; b[0] = 2; } change(a); console.log(a); //[1,2,3]
問題4解答:change(b)執(zhí)行過程是這樣的,a對(duì)象傳入change函數(shù),將值和地址復(fù)制給b。b=2這句,此時(shí)b變成值類型了,并不涉及地址引用的問題,之后b[0]=2這句實(shí)際上毫無意義,因?yàn)榇藭r(shí)b已經(jīng)不是數(shù)組了,自然不具有b[0]這樣的索引方式。所以b與a的地址引用關(guān)系其實(shí)在b=2之后就消失了。此時(shí)外界的a仍然是[1,2,3];
以上所述就是本文的全部?jī)?nèi)容了,希望大家能夠喜歡。
相關(guān)文章
利用jquery實(shí)現(xiàn)實(shí)時(shí)更新歌詞的方法
這篇文章主要給大家介紹了如何利用jquery實(shí)現(xiàn)實(shí)時(shí)更新歌詞的方法,文中給出了詳細(xì)的實(shí)現(xiàn)思路和示例代碼,對(duì)大家的參考借鑒具有一定的價(jià)值,有需要的朋友下面來跟著小編一起學(xué)習(xí)學(xué)習(xí)吧。2017-01-01jQuery中text() val()和html()的區(qū)別實(shí)例詳解
這篇文章主要介紹了jQuery中text() val()和html()的區(qū)別實(shí)例詳解的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06基于Bootstrap+jQuery.validate實(shí)現(xiàn)Form表單驗(yàn)證
這篇文章主要介紹了基于Bootstrap+jQuery.validate實(shí)現(xiàn)Form表單驗(yàn)證,需要的朋友可以參考下2014-12-12jQuery實(shí)現(xiàn)動(dòng)態(tài)刪除LI的方法
這篇文章主要介紹了jQuery實(shí)現(xiàn)動(dòng)態(tài)刪除LI的方法,結(jié)合實(shí)例形式分析了jQuery針對(duì)頁(yè)面元素動(dòng)態(tài)操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-05-05jQuery實(shí)現(xiàn)判斷滾動(dòng)條到底部
這篇文章主要介紹了jQuery實(shí)現(xiàn)判斷滾動(dòng)條到底部的相關(guān)資料,需要的朋友可以參考下2015-06-06用Jquery選擇器計(jì)算table中的某一列某一行的合計(jì)
本節(jié)主要介紹了用Jquery選擇器計(jì)算table中的某一列某一行的合計(jì),需要的朋友可以參考下2014-08-08jquery easyui combox一些實(shí)用的小方法
這篇文章主要介紹了jquery easyui combox一些實(shí)用的小方法,有需要的朋友可以參考一下2013-12-12