[JavaScriptWeird]No.52 運算子「=」

前言

上次提到 Primitive Types 與 object 的其中一個差別,接下來我們討論另一個差別,那就是對於運算子「=」,兩者的表現並不一樣。

使用運算子「=」賦值

賦值就像字面上的意思一樣,重新給予一個值,而我們也可以喚醒另外一個世界線的記憶:

這也達到了當初做筆記的目的,因為有之前的筆記,所以我在學習相同的觀念但不同講法時,我可以交叉驗證自己吸收得如何。

由另個世界線的記憶我們可以知道:

  • 「=」的優先性為 3
  • 「=」為「右相依」 (right-to-left)
  • Primitive Types 是傳值 (By Value) 的
  • Object 是傳參考 (By Reference) 的

例子驗證

1
2
3
4
5
var a = 10;  
var b = a;
console.log(a, b); // 10 10
b = 200;
console.log(a, b); // 10 200

上面這個如我們預期,因為 Primitive Types 是傳值的,我們創造一個新的變數 a ,並且令 b = a ,變數 b 會指向一個新的記憶體位址,並拷貝那個純值 10 ,放到新的記憶體位址

接下來做點改變

1
2
3
4
5
6
7
8
var obj = {  
num: 10
}

var obj2 = obj;
console.log(obj, obj2);
obj2.num = 20;
console.log(obj, obj2);

首先使用物件實體語法建立了 obj 物件,接著使用等號運算子將右邊的 objobj2 ,而物件是傳參考的,也就是說這兩個物件目前指向的記憶體位址相同,所以結果才會是這樣。

上面算是一個小複習,畢竟在另個世界線有同樣的範例了。

然而 Array 在最底層也是物件,所以傳參考的情況也適用:

1
2
3
4
5
var arr1 = [];  
var arr2 = arr1;
console.log(arr1, arr2); // [] []
arr2.push('arr2');
console.log(arr1, arr2); // ["arr2"] ["arr2"]

以上就是 Primitive Types 與 object 的另一個差別。

「=」的小陷阱

延續上面那個物件的例子,如果改成這樣:

1
2
3
4
5
6
7
8
9
var obj = {  
num: 10
}
var obj2 = obj;
console.log(obj, obj2);
obj2 = {
num: 20
};
console.log(obj, obj2);

雖然上面提到物件是傳參考的,但是在這個例子中雖然 obj2obj 一度指向同樣的記憶體位址,但是隨即又被等號運算子重新賦與一個新的物件,此時 obj 就與 obj2 指向不同的記憶體位址了。

所以陷阱在哪裡

透過上下兩個相似例子的比較,我們需要搞清楚以下:

  • obj2.num = 20;
  • obj2 = { num: 20 };

雖然都是使用等號運算子,但是意義上是不太一樣的。

回想一下第一點的那個例子,

  • 一開始 objobj2 指向同一個位址
  • 使用等號運算子把新的數值賦值給 obj2 內的屬性 num
  • 新的數值產生也會被存放在某個記憶體位址,
  • 但因為賦值的對象並不是 obj2 ,所以沒有影響到 obj2 的位址。

第二點的例子,

  • 一開始 objobj2 指向同一個位址
  • 使用等號運算子把新的物件賦值給 obj2
  • 新的物件產生也會被存放在某個記憶體位址
  • 此時賦值的對象是 obj2 ,等號運算子把新物件的記憶體位址給了 obj2

也就是說,此時 objobj2 就不相干了。

另外還有個初學者會遇到的例子,關於等號運算子的,也就是少打等號的問題,一般我們都會這樣寫

1
2
3
4
var a = 1;  
if (a === 1){
console.log(123);
}

但如果少打了等號:

1
2
3
4
var a = 1;  
if (a = 20){
console.log(456);
}

結果就會出現非預期的輸出,原因是這樣子寫就如同:

1
2
3
4
5
var a = 1;  
a = 20;
if (a){
console.log(456);
}

所以這個 if 內的東西一定會執行。

[心得]

這個小節的內容個各別散落在原本世界線的不同文章上,透過這樣的重新整理,又再次的複習了這些概念,其中我最喜歡的是小陷阱的部分,可以藉由這些陷阱,再度的仔細思考是不是哪個環節想錯了。

我開始喜歡寫紀錄文了,這有點像鄧不利多的儲思盆,可以把記不住的東西給寫下來,然後不占據腦容量,需要的時候在到儲思盆看一下~

雖然暫時沒辦法全部都記住,看久、摸久、寫久總會是我的。

0%