在前面的篇章有提到在JavaScript裡,要比較兩個值是否一樣要用3個等號而不是兩個等號,這是因為JavaScript有一項特性,叫做coercion。
coercion指的是將資料從一種型態轉換成另一種型態,在某些情況下JavaScript會根據它自己的判斷將資料轉換成另一種型式。
var a = 1 + '2';
console.log(a) // 12
console.log(typeof a) // string
上面這個案例我把兩個不同型別的變數做運算,這個時候JavaScript 會在執行的過程中會去猜測你的程式碼是什麼意思,因此當他看到了數字 + 字串時,他會自己判斷為你可能是要2個字串連接起來,所以他會把1從number強制轉換成 string,所以才會出現12。
所以這個時候,當我們用 typeof 來查看型別時就會發現,a 的型別已經變成了string了。
了解了什麼是coercion之後,我們來看看下一個練習:
console.log(3 < 2 < 1)
按照我們的數學基礎這題的答案應該會是false,但實際結果卻是true。
為什麼會變成這樣?一樣我們一步一步拆解:
首先先比較3 < 2 ,這個答案會是false,接下來再把得到的結果去跟後面的比就會變成false < 1。
疑,這時候發現兩邊型別不同耶,所以JavaScript 引擎就會執行Coercion,把boolean轉換成number,因此false就會變轉換成0,所以false < 1 會變成 0 < 1,因此出來的結果會是true
因此當我們看到題目 console.log(1 < 2 < 3)出來的結果為true時,並不要開心太早,因為不是我們數學知識認為的那樣,而是因為小於的associativity為左到右,因此會先比較1 < 2然後再比較 true < 3。因為型別不一樣執行Coercion,把true轉換成1,所以console.log(1 < 2 < 3)結果才會是true。
看到這裡 boolean 會被強制轉換,我還蠻好奇其他Primitive type被強制轉換成number會變成怎樣,來看一下其他Primitive type被強制轉換會變成什麼吧。
console.log("false:", Number(false));
console.log('true:', Number(true));
console.log("string 3:", Number('3'));
console.log("undefined:", Number(undefined));
console.log("null:", Number(null));
輸出結果為:
false: 0
true: 1
string 3: 3
undefined: NaN
null: 0
這時候發現一個很有趣的地方了,undefined會被轉換成 NaN 也就是 not a number,但null卻是會被轉換成0。
這也就是會導致很多奇怪錯誤的地方,尤其是在我們在使用if時。
因此我們會在if中加入條件時,例如當…等於…的時候,在其他語言都是用雙等號,但是因為JavaScript 的Coercion特性,在JavaScript裏面當我們要去判斷2個東西是否一樣時我們會用3個等號也就是“===”
既然提到if,那就不能提到boolean,在判斷是裡面我們也常會使用到,先來看看其他Primitive type在什麼時候被強制轉換會變成false。
console.log("string '':", Boolean("")); //false
console.log("undefined:", Boolean(undefined)); //false
console.log("null:", Boolean(null)); //false
console.log("number 0:", Boolean(0)); //false
由上面結果我們可以得知,空字串、數字0、undefined、null都會被轉換成false
那我們來看看下面這段code,我想要的結果是:當今天只要有任何值就必須印出:Something is there
var a;
if (a) {
console.log(Something is there)
}
由上面的輸出結果我得知,當今天變數是空字串、undefined 跟null 時,他的boolean會是false
因此這段code執行後不會印出任何東西,但這不是如我想要的,因此當我把code變成這樣:
var a = 任何數字或字串;
if (a) {
console.log(Something is there)
}
雖然這樣我們可以完成我們的要求,但因為上面我們測試過,當Boolean(0)時會回傳false這時候我們就不能只是單純這樣寫,因為有可能我們會輸入0,因此要改成:
var a = 任何數字或字串;
if (a || a === 0) {
console.log(Something is there)
}
這樣就可以了
由於JavaScript是我目前記憶裡唯一一個程式語言(學生時代學過C++跟Java但都忘光了),因此我並不覺得這很奇怪,但看到有學過其他語言的人看到這東西而滿臉困惑的表情才驚覺,這可能真的是很特別的一個特性XDD