iT邦幫忙

DAY 5
6

Javascript系列 第 5

Javascript中的傳遞參考與closure (1)

  • 分享至 

  • xImage
  •  

I.傳值與傳參考 --> now
II. 傳參考與closure (1)
II. 傳參考與closure (2)
II. 傳參考與closure (3)
我記得以前學 C++ 的時候,對傳值、傳參考跟傳址有很多的討論,但在 js 好像比較少?最近比較常用 PHP ,以 PHP 為例,來做一個老問題:請實做一個函式,輸入兩個簡單型別的變數,例如兩個數字,然後將這兩個變數互相交換。

<?php
$a = 1;
$b = 2;

echo "($a, $b)";	// (1, 2)
swap($a, $b);
echo "($a, $b)";	// (2, 1)

function swap(&$a, &$b)
{
   $temp = $a;
   $a = $b;
   $b = $temp;
}

這邊會看到 swap 中參數的部分加了一個 &,這是告訴 PHP 說這邊要傳遞的是變數的參考,但在 js 中無法做到這件事情,這也不是說 js 中沒有「值」跟「參考」的區別,只是在函式的參數傳遞時,無法明確指定這樣做,我想,這可能是 js 中比較少討論這塊的原因。

在 js 中,一般討論到值與參考時,大概就是在介紹變數的時候,我們都知道 js 中型別分為兩種,一種是簡單型別,像是數值、字串、布林值、null 與 undefined。其他的所有的值都是物件,通常物件在傳遞時,都是傳遞參考。

到底傳遞值跟參考有什麼差別?

值的傳遞是指在傳遞的時候,在記憶體中會要一塊新空間,然後將原本的值複製到其中,原本變數的修改或新變數的修改,都不會互相影響,例如:

var a = 1;
b = a;
console.log(a, b);	// 1, 1
b = 2;
console.log(a, b);	// 1, 2  a 還是 1





function swap(first, second){
   var temp = first;
   first = second;
   second = temp;
   console.log(first, second);	// 2, 1 交換成功
}
var a = 1, b = 2;
swap(a, b);
console.log(a, b);   // 1, 2 沒有被交換

物件的行為就不是這樣了,物件是傳遞參考,參考有點抽象,就先把它跟位址混在一起討論。可以想像在記憶體中,要兩塊空間,一塊空間是真的存資料,另外一塊空間,則是存那塊存資料的空間的位址。當要傳遞的時候,是傳遞這個位址;當要取資料的時候,就先去看一下位址是多少,在循着位址去找到真正的資料的儲存地方。也正因為存取時,是真的找到該資料的儲存地,所以修改的話會互相影響。

function swap(p){
   var temp = p.a;
   p.a = p.b;
   p.b = temp;
}

var obj = {
   a: 1,
   b: 2
};
console.log(obj);  // { a: 1, b: 2 }
swap(obj);
console.log(obj);  // { a: 2, b: 1 } 

在這個範例中,可以清楚地看到 a 跟 b 被交換了。

在記憶體中到底是怎麼一回事呢? 記憶體中會分兩種區塊:stack 跟 heap。
stack 是用來存放簡單型別的變數與物件的參考,這裡的資料大小是必須確定的,存取的速度也比較快。
heap 是用來儲存物件真實資料的地方,由於我們通常不知道物件裡頭會有哪些東西,所以是動態的,速度也就比較慢一點。

回顧上方兩組範例程式,分別宣告了這些變數:

var a = 1, b = 2;
var obj = {
   a: 1,
   b: 2
};

這些在記憶體中會長什麼樣子呢?我們來畫個示意圖:

當我們把obj傳進swap時,又會發生什麼事呢?

記憶體中會多一塊變數 p,但 p 存的也是 obj 所存的那個位址,當要修改 p 時,就是循著這個位址去找到真正儲存資料的地方,對 p 的修改其實就是對 obj 的修改,都是修改真正儲存資料的地方,所以就會互為影響。

這部分即使沒有特別討論,但大家平常應該很常在使用,會想要特別提出來說,是因為牽涉到 closure,這個就靜待下回分解啦。


上一篇
javascript中的位元運算子 (3)
下一篇
Javascript Closure的用法 - Memoization
系列文
Javascript7
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
weilungjae
iT邦新手 5 級 ‧ 2013-09-27 00:19:32

我超喜歡這篇,超喜歡swap,這種簡單又有趣的東西!!!!飛

azole iT邦新手 5 級 ‧ 2013-09-27 00:23:45 檢舉

那快按各推阿!

我要留言

立即登入留言