0%

008重新認識JS-Day01-筆記4

JavaScript 運算子(Operator)

算數運算子之一: 四則運算

加號(+)

Infinity, -Infinity, NaN 皆屬於「特殊數字」

當NaN在運算式中,其結果必為NaN
ex:

1
2
console.log(10 + NaN); // NaN
console.log(Infinity + NaN); // NaN
若加號的某一方不是數字,而是「字串」呢?

若其中一方是字串,則另一端會自動會被轉型為字串,接著,再連接再一起。
ex:

1
2
3
100 + "100";  // "100100"
100 + "ABC"; // "100ABC"
"XZY" + "ABC"; "XZYABC"

所以,當一端是字串型別,
而另一端是number型別、boolean型別、Object型別時,會先去呼叫toString()方法,
將他們轉為字串。
若另一段是nullundefined,則通過toString()轉型後,分別會是字串null和字串undefined
ex:

1
2
3
4
5
6
7
8
9
10 + 'abc'; // '10abc'
true + 'abc'; // 'trueabc'
100 + {}; // '100[object object]'
'123' + null; // '123null'
'123' + undefined; // '123undefined'

--若一方是數字型別,另一方是null或undefined的話呢?--
123 + null; // 123,而null會被Number()轉成數字型別,轉型的結果是0,故123+0等於123
123 + undefined; // NaN,因為undefined經過Number()轉型結果是NaN,故123+NaN等於NaN

減號(-)

若減號的某一方不是數字呢?

若另一端是基礎型別但不是number型別,則JS會先將它分用Number()方法嘗試將它們
轉成數字型別
ex:

1
2
3
4
5
6
100 - '50'; // 50
100 - 'abc'; // NaN
100 - false; // 100
100 - true; // 99
100 - undefined; // NaN,故undefined藉由Number()轉換結果是NaN,故100+NaN結果是NaN
100 - null; // 100

若另一端是物件型別

若是物件型別,並透過透過valueof()方法先求得相對應的值,如過得到NaN,則結果為NaN。
如果,該物件沒有valueof()方法,則是先透過toString()轉成「字串」,
接著,再由Number()方法,嘗試將此字串轉換成數字型別,再運算。
ex:

1
2
3
console.log(100 - {}); // NaN,因為這個物件沒有valueof()方法,先用toString()方法轉成字串,轉換結果為'[object object]'。
接著,再對這個字串進行Number()進行數字轉換,
轉換結果是NaN。 而100 + NaN 的結果是NaN。

ex:

1
2
3
4
5
6
7
8
9
10
function obj(number){
this.num = number;
}
obj.prototype.valueof = function(){
return this.num;
}

var a = new obj(60);
console.log(100 - a); // 40,因為,物件a有valueof()方法,並回傳60。
故100 - 60 = 40。

乘號(*)、除號()、取餘數(%)

這三個運算子的特性其實差不多,功能也比較簡單,所以,就把三個同樣的特性放在一起紀錄

若乘號、除號、取餘數的某一方不是數字呢?

若另一端不是數字型別,JS會先用Number()方法轉型,再計算。
如果,轉不出來的話,計算結果就是NaN
ex:

1
2
100*"abc"; // NaN
100*true; // 100

算數運算子之二: 一元運算子(Unary Operator)

只要單個數值就可以完成運算,這類的運算子就叫做「一元運算子」。

若正號(+)或負號(-)後面接的不是數字型別的值呢?

JS會先透過Number()的方式嘗試轉型,接著,再看它前面的正負號,再來決定它的正負值。

1
2
3
4
5
6
7
8
9
10
11
12
var a = "10";
var b = "-10";
var c = "abc";

console.log(+a); // 10
console.log(-a); // -10
console.log(+b); // -10
console.log(-b); // 10
console.log(+c); // NaN
console.log(-c); // NaN
console.log(+true); // 1
console.log(+false); // 0

書中有提到一個小技巧,如果覺得在某些變數前面加上Number()來做數字型別的轉型很麻煩的話,
可以直接在變數的前面加上正號(+),就可以將它轉型成數字型別了。

若後面接的是物件型別,會先透過物件valueof方法來求出對應的數值,再依照正號或負號來決定其值

ex:

1
2
3
console.log(+(function{console.log('Hi)}));  // NaN,因為,函式是物件的一種,且沒有valueof的函式會回傳值,
// 而JS會對它做Number()做數字型別轉換,但轉換結果是NaN,所以,
// 結果是NaN

算數運算子之三: 比較運算子

比較運算子用來比較運算子兩側的數值(不管是什麼型別),比較後會得到truefalse
針對不同型別的數值,JS會自動將運算子兩側的數值轉成相同型別後,再做比較。

「相等」== 與 「全相等」===

「當兩個等號==」時,JS會自動替數值做自動轉型
「當三個等號==」時,JS不會自動替數值做自動轉型

所以,在「當三個等號===」的狀況下,只有在雙邊的「型別」和「數值」都相同下,才會回傳true

所以,強烈建議用 === 取代 ==,不然,會出現無法理解的結果XDD

「不等於」!= 與 「全不相等」!==

「!=」時,JS會自動替數值做自動轉型
「!== 」時,JS不會自動替數值做自動轉型

所以,強烈建議用 !== 取代 !=,不然,會出現無法理解的結果XDD