var a = 10; var b = 10; //在基本型別的時候,會認為這兩個變數的「值」是相等的,因為兩個變數的數值都是 10 console.log( a === b ); // true a=20; var c=a; console.log("a is "+a); // a is 20 console.log("b is "+b); // b is 10 console.log("c is "+c); // c is 10
變數 c 的值是透過複製變數 a 的值而來。
但變數 a 更新之後,不會去影響變數 c 的數值。
表面上看起來變數 c 的內容是透過複製變數 a 而來,但此時若變數 a 的內容為基本型別時,實際上變數 c 是去建立了一個新的值,然後將變數 a 的內容複製了一份過來。
Call By Value
當我們在建立「基本型別」 的變數時,根據上面的例子,a 會存在記憶體中的某個位置。這時候,當我指定另一個變數 c,它的值等同於 a 的時候,c 實際上會建立另一個獨立的記憶體位置,接著再把 a 的值存在這個獨立的記憶體位置。也就是說, a 和 b 其實是存在於兩個不同的記憶體位置,因此彼此並不會乎相干擾影響,這種情況,我們就稱為 Call By Value 。
物件型別
JavaScript 的物件都應該看作是一個「實體」。
1 2 3 4 5 6 7 8 9 10 11
var a= { value: 10 };
var b= { value: 10 }; //// a 與 b 不是同一個實體。 console.log( a === b ); // false
b=a; a.value=20; console.log(a.value); // 20 console.log(b.value); // 20 console.log( a === b ); // true
當我將變數 a 設立成一個 Object 時,一樣會存在記憶體中的某個位置;但是當我建立一個變數 b,並且把變數 b 的值等同於 a 時,這時候並不會再給予它一個新的位置,而是將 b 指定到物件 a 的位置,讓變數 a 和 b 使用相同的記憶體位置,因此,當 a 的值改變的時候 b 的值也會改變,這種情形我們就稱為 Call By Reference。
例外情況
如果使用 object literal 的方式指定物件的值,那麼就會是 Call by value:
1 2 3 4 5 6 7 8 9
var a= { value: 10 };
var b;
b=a; a={value: 20};
console.log(a); // console.log(b); //
在這種情況下,因為它並不清楚 a 的內容是已經存在的,所以會建立一個新的記憶體位置來存放 a 物件裡面的內容。
Call by sharing
JavaScript 實際上是另一種稱做「call by sharing」的模式,其特點在於,當 function 的參數,如 function changeValue(obj){ ... } 中的 obj 被重新賦值的時候,外部變數的內容是不會被影響的。