我們將運算子的優先性和相依性以及強制型轉 一起結合起來看,
來解釋一些 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 中看結果:
使用嚴格等於或不等於不會將我們要比較的值強制轉型,
他們是不同的運算子(特別的函數)。