這篇文章主要介紹了javascript的變量、傳值、傳址、參數之間關系的相關資料,需要的朋友可以參考下
先把收獲晾一下:
1.javascrip變量包含兩種類型的值,一種為引用類型的值,一種是基本類型的值。引用類型包括:Array,Object,Function(可以這么理解,非基本類型的都是引用類型);5種基本類型包括:undefined,null,string,boolean,number
2.函數的參數的傳遞的機制是復制變量值。
書上說:”把函數外部的值復制給函數內部的參數,就和把值從一個變量復制給另一個變量一樣?;绢愋偷膫鬟f如同基本類型變量的復制一樣,而引用類型的則如同引用類型變量的復制一樣。“
”當一個變量復制引用類型的值時,同樣也會將存儲在變量對象中的值復制一份放到為新變量分配的空間中。不同的是這個值的副本實際上是一個指針,而這個指針指向存儲在堆中的一個對象。復制操作結束后,兩個變量實際上將引用同一個對象。因此改變其中一個變量,就會影響到另一個變量。“
【注意:復制引用類型的值,才是傳址】
3.參數實際上是函數的局部變量。
----------------------------------------------------------------------------
基本概念的解釋:
傳值:把A的數值傳到B,改變B,A不會跟著變,B存的是跟A一樣的值;
傳址:把A的地址傳到B,改變B,A同時跟著變,B存的只是A的地址(類似電腦的快捷方式)。
一個具有值類型(value type)的數據存放在棧內的一個變量中。即是在棧中分配內存空間,直接存儲所包含的值,其值就代表數據本身。值類型的數據具有較快的存取速度。
一個具有引用類型(reference type)的數據并不駐留在棧中,而是存儲于堆中。即是在堆中分配內存空間,不直接存儲所包含的值,而是指向所要存儲的值,其值代表的是所指向的地址。當訪問一個具有引用類型的數據時,需要到棧中檢查變量的內容,該變量引用堆中的一個實際數據。引用類型的數據比值類型的數據具有更大的存儲規模和較低的訪問速度。
----------------------------------------------------------------------------
下面是三個問題。
為什么change(a)函數執行完之后,外面的a沒有受干擾呢?
【問題1】:
- <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解答:因為change(a)的執行過程是這樣的,首先將對象a(數組)傳入到change以后,被復制給change的參數a。而后a=2是一個賦值語句,變成傳值。此時a=2是值類型,并不涉及引用地址的問題。所以并沒有影響外部的a。
為什么change(a)函數執行完之后,外面的a受到干擾呢?
【問題2】:
- <script>
- var a = [1, 2, 3];
- function change() {
- a = 2;//傳值
- }
- change();
- console.log(a); //2
- </script>
問題2解答:當執行change()的時候,函數在自己的執行環境中找尋作用域鏈,活動對象(activation object)并不包含變量a,于是沿著作用域鏈向上找,找到全局執行環境,發現變量a,于是此時函數內部的a和外部a在內存上是同一個地址,自然函數內部a變了,外部也會跟著變。
解析:問題2和問題1的區別在于,問題2并沒有引入參數,所以不涉及復制變量的事情。
為什么change(a)函數執行完之后,外面的a受到干擾呢?
【問題3】:
- <script>
- var a = [1, 2, 3];
- function change(b) {
- b[0] = 2;
- }
- change(a);
- console.log(a); //[2,2,3]
- </script>
問題3解答:這個和問題1非常類似,唯獨不一樣的就是a=2,換成了b[0]=2,我一開始也很疑惑,不說復制嗎?參數b應該是個復制值,怎么會影響到外面的a呢?
的確,change函數執行時,參數b是a的復制值。因為a是引用類型,所以在函數內部是b和a按引用來訪問的是一個地址的對象。b[0]=2的出現,并不影響在函數內部b和a引用的是同一個對象。
為什么change(a)函數執行完之后,外面的a沒有受到干擾呢?
【問題4】:
- 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)執行過程是這樣的,a對象傳入change函數,將值和地址復制給b。b=2這句,此時b變成值類型了,并不涉及地址引用的問題,之后b[0]=2這句實際上毫無意義,因為此時b已經不是數組了,自然不具有b[0]這樣的索引方式。所以b與a的地址引用關系其實在b=2之后就消失了。此時外界的a仍然是[1,2,3];
以上所述就是本文的全部內容了,希望大家能夠喜歡。
|
新聞熱點
疑難解答
圖片精選