JavaScript 核心觀念(26)-物件-物件的參考特性

前言

接下來來講講物件傳參考,基本上物件傳參考的特性如果沒搞清楚是很容易踩雷的。

物件傳參考

首先先來看一下一般常見的傳值

1
2
3
var a = 'Ray';
var b = a;
console.log(a, b); // Ray, Ray

我們可以看到 b 是接收了 a 的值,所以 b 出來的就會是 Ray,那麼如果我們修改 b 呢?這時候第二次的 console.log(a, b) 會是什麼?

1
2
3
4
5
var a = 'Ray';
var b = a;
console.log(b); // Ray;
b = 'qq123';
console.log(a, b); // Ray, qq123

這邊基本上沒有什麼太大問題,但是在物件上面就會有點特別,首先先讓我們來看一個物件範例

1
2
3
4
5
var a = {
name: 'Ray',
}

var b = a;

在這邊我們可以看到 a 物件賦予到 b,這時候若我們修改 b.name 再來看 console.log(a.name, b.name); 會發生什麼事情呢?

1
2
3
4
5
6
7
8
9
var a = {
name: 'Ray',
}

var b = a;

b.name = 'qq123';

console.log(a.name, b.name); // qq123, qq123

這時候很奇妙的事情發生了 a.name 竟然跟著被修改,接下來若輸入 console.log(a === b); 也會得到 true 的結果,在一開始的範例中所使用的是純值的概念去賦予值,而後面的範例則是物件

值與參考

基本上 JavaScript 在賦予值的時候是採用兩種特性去運作的

  • Call by value
  • Call by reference

(JavaScript 其實是 Call by Sharing,後面章節會再解釋,先簡單理解就好)

傳值與傳參考

這邊簡單來講傳值就只是傳遞資料過去,而傳參考就是我參考原本的整份資料,舉例來講學校考試時,對面寫什麼我就寫什麼的概念一樣。

而物件本身在概念就是一個記憶體,因此若傳遞的是物件,那麼其實你是在傳遞整個物件給另一個變數就如剛剛的範例相同

1
2
3
4
5
var a = {
name: 'Ray',
}

var b = a;

物件傳參考

但是如果你是重新賦予一個物件,那麼就會發生不同的狀況

1
2
3
4
5
6
7
8
9
10
11
var a = {
name: 'Ray',
}

var b = a;

b = {
name: 'Ray',
}

console.log(a === b);

儘管內容是相同的,但是在物件的記憶體位置上,其實是不同的位置,但若你是傳遞物件中的值,那麼就不會受到任何影響,因為這是傳值

1
2
3
4
5
6
7
var a = {
name: 'Ray',
}

var b = a.name;
b = 'qq';
console.log(a.name, b); // Ray, qq

那麼最簡單的辨識方式就是,當若你看到傳遞的是一個物件 {} 那麼就會有傳參考問題,當然函式或是陣列都會有傳參考問題,因為這兩者在 JavaScript 也是屬於物件

1
2
3
4
5
6
7
8
9
10
11
12
13
function fn() {}

fn.test = 'Ray';

var b = fn;
b.test = 'qq'
console.log(fn.test, b.test); // qq, qq


var a = [1, 2, 3];
var b = a;
b[0] = 123;
console.log(a[0], b[0]); // 123, 123

參考文獻

0%