iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 11
0
Modern Web

教練我想學 JavaScript 系列 第 11

Day 11 比較運算子

我們將運算子的優先性和相依性以及強制型轉 一起結合起來看,
來解釋一些 JavaScript 看似奇怪的行為
當我們討論時,你就會更瞭解
更熟悉一些我們講到一些奇怪的東西
舉例來說:

console.log(1 < 2 < 3);

你期待結果是什麼?
這些是小於運算子
會回傳布林值
可能是 true 或 false

在 Consoel 中的結果為:

好的,讓我們改成3小於2小於1

console.log(3 < 2 < 1);

會是false對吧
3不小於2 2不小於1
我們到 Console 中看結果:

為何會回傳true?

我們可以用我們既有的知識回答這個問題
運算子優先性和相依性
有兩個小於運算子 所以優先性一樣
什麼決定誰先執行?
相依性

小於運算子是左到右相依
表示最左邊的會先執行
所以3小於2會回傳什麼?

console.log(3 < 2);

我們到 Console 中看結果:

我們知道是 false

所以真的發生的事情是第二個運算子當它被呼叫 傳入參數1和 false
JavaScript 的運算子想要做的是
當我給它一個值 但不是預期中的型別
它想要兩個數字,而我給它一個數字和一個布林
它會試著強制型轉這個布林為數字
false 轉換成數字是什麼?

使用 JavaScript 內建函數 Number 來將 false 轉成數值來看
我們可以直接在 Console 看到:

我不建議你用這個
但這對於看如何強制型轉很有用

然而我們會在之後談談這個
要不要使用內建函數的議題

只是讓你知道強制型轉成什麼 我用這個 Number 函數
我可以給一個值,任意值 它會展示給我看 將會轉型成什麼 因為它會試著轉換它為數字

例如:

這很有趣
其實 true 和 false 可以被轉型 false 變成0;true 變成1

回到這個例子:

console.log(false < 1);

所以這代表什麼?

當這個小於運算子被呼叫
JavaScript 轉換 false
JavaScript 其實在執行這個陳述句0小於1?

因為這個轉換布林為數值型別
這變成0

console.log(0 < 1);

所以0小於1?
變成 true.

這一系列的函數被呼叫 3小於2小於1
雖然從人類角度
這很明顯是錯的
但從 JavaScript 引擎角度來看
這行程式碼 其實是很合理的
答案是 true 因為函數運算子執行的順序以及值的強制型轉
但當我們可以知道如果你不瞭解
你可能會覺得 JavaScript 真的很詭異

所以我們看出強制型轉可以導致一些
從人類角度來看得奇怪結果
但從電腦角度
從 JavaScript 角度, 非常合理
不是每個轉型的情況都是這樣可以預期的
例如,我可以轉型false或true成數字
我可以轉型字串為數值 如果字串是數字的話

我們在到 Console 中看些列子:

你看到了嗎
不是每次轉型的結果都很明顯
你以為 undefined 和null 會一樣,但沒有,
所以這有很多特殊情況 像是 undefined 和 null 不會照你預期的呈現
null, 雖然會轉型為0,在某種情況下像是 null 小於 1, 但它不會在比較的時候轉型為0

所以雖然強制型轉威力強大 它也可能很危險

讓你看另一個例子:

用空字串和0 這是 true.
所以如果我有空字串和 false 也是 true.
你可以看到這有問題 因為
它同時也想要轉換這些值
但它會讓你的程式碼很難預期
會發生什麼事
所以我們怎樣解決?

回到運算子優先性表格
看到雙等號 表示相等
但這邊還有三等號 表示完全相等

===

這邊也有不相等 用驚嘆號表示
這個是完全不相等,用驚嘆號加上雙等號

!==

這是個標準運算子 但不會強制轉換你的值
這會拯救你的人生

我們來看些範例:

三等號這個內建的運算子函數
認定這兩個東西是不同型別,所以不相等
所以用三等號當比較值的時候可以避免有些奇怪的潛在錯誤

我們整理上述觀念來看些實際範例:

var a = 0;
var b = false;

if(a == b) {
  console.log('They are equal!');
}else {
  console.log('Not equal!');
}

猜一下結果是否跟你想的一樣,
我們到 Console 中看結果:

再來我們用不等於來看:

var a = 0;
var b = false;

if(a != b) {
  console.log('They are not equal!');
}else {
  console.log('Equal!');
}

猜一下結果是否跟你想的一樣,
我們到 Console 中看結果:

如果我們改成用3個等號(嚴格等於)來判斷呢?

var a = 0;
var b = false;

if(a === b) {
  console.log('They are equal!');
}else {
  console.log('Not equal!');
}

猜一下結果是否跟你想的一樣,
我們到 Console 中看結果:

接著我們用嚴格不等於來看,

var a = 0;
var b = false;

if(a !== b) {
  console.log('They are not equal!');
}else {
  console.log('Equal!');
}

猜一下結果是否跟你想的一樣,
我們到 Console 中看結果:

使用嚴格等於或不等於不會將我們要比較的值強制轉型,
他們是不同的運算子(特別的函數)。


上一篇
Day 10 運算子
下一篇
Day 12 存在(exeistence)、布林(Boolean) 與預設值
系列文
教練我想學 JavaScript 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言