動態型別和強制型轉真的很有用嗎
讓我們談談存在(exeistence)和布林(boolean)
我打開開發者工具
我使用內建函數
有個布林內建函數可以轉換
雖然不建議用內建函數
但內建函數方便我們得知一個值被強制轉型後的值是什麼
所以,如果我轉換成布林
true 或 false 讓我們來看看:
Boolean(undefined);
Boolean(null);
Boolean("");
當我把 undefined 轉成 Boolean,
undefined 變成 false
null 呢?
null 是 false.
空字串呢?
空字串也是 false.
所以這些東西都表示不存在 所以轉換成 false
如下圖:
可以利用這些特性
所以,如果我轉換成布林 true 或 false 讓我們來看看
當我把 undefined 轉成 Boolean,
undefined 變成 false
那 null 呢?null 是 false.
空字串呢?空字串也是 false.
所以這些東西都表示不存在 所以轉換成 false
可以利用這些特性
來看個例子:
var a;
// goes to internet and looks for a value
if (a) {
console.log('Something is there');
}
宣告var a,但不設值
假設我有一些程式碼 可以到網路上尋找值
如果找到了設定 a 為那個值
我可以用 if 陳述句
在 if 陳述句括號裡東西
它會試著轉換為布林
記得在執行環境的創造階段
會在記憶體為這個變數建立位置,然後它會做什麼?
它會把它設定為什麼初始值?
對, undefined.
undefined 會轉換成什麼?
False.
所以我們可以用強制型轉來檢查a是否存在 如果最後 a 是 undefined,因為從未設值,
或 a 是 null,程式碼如下:
var a;
// goes to internet and looks for a value
a = null;
if (a) {
console.log('Something is there');
}
當我照著邏輯這樣做時 我仍然不會得到任何東西:
如果 a 是空字串,程式碼如下:
var a;
// goes to internet and looks for a value
a = "";
if (a) {
console.log('Something is there');
}
仍然會轉為 false 所以沒有東西會出現:
但當我有像是字串的東西,不是空的,
程式碼如下:
var a;
// goes to internet and looks for a value
a = 'hi';
if (a) {
console.log('Something is there');
}
到 Console 中看結果:
看到如何運作了嗎
我們可以利用強制型轉的特性
來檢查變數有沒有值
一個不是 undefined, null, 或空字串的值
現在有個危險的地方
0強制轉型後也是 false
所以如果變數最後的值為0
就有問題
因為0不是不存在
這是個有效的值
程式碼如下:
var a;
// goes to internet and looks for a value
a = 0;
if (a) {
console.log('Something is there');
}
但 a 會被強制轉型為變成布林值
所以我重新整理,不會得到console.log 因為它是 false
0 變成 false.
在 Console 中結果:
所以我可以這樣做 如果我想到這個可能性的話,
我會在 if 條件判斷中添加 || a === 0.
程式碼如下:
var a;
// goes to internet and looks for a value
a = 0;
if (a || a === 0) {
console.log('Something is there');
}
這樣做的話
運算子優先性和相依性表格
拉下來 ||
運算子的優先性比 ===
運算子低
所以「完全相等」函數會先執行,在這個「或」函數之前
首先它會執行 ===
運算子, 因為使用 ===
運算子不會在比較前強制轉換為相同的型別, 因為變數 a 的值為 0 ,透過 ===
運算子進行比較後會回傳 true 然後執行 console.log
||
運算子左邊的變數 a 會被強制轉型,因為變數 a 的值是 0 在 if 判斷內會被轉型為 false
因為 if 判斷 () 內會預期回傳布林值
然後這會變成 if (false || true)
false || true 會回傳 true
在這個函數中,其中一個是 true 或都是 true 的話 就會回傳true
所以這變成true
所以我會看到 Something is there.
所以如果變數 a 的值不是 undefined 不是 null, 不是空字串
你可能不需要這樣做,
因為如果它的值幾乎不太可能會是 0 的話可能只要這樣寫 if(a) 看它存不存在就好了
程式碼如下:
var a;
// goes to internet and looks for a value
if (a) {
console.log('Something is there');
}
這些技巧在開發中很常使用,因此要把這觀念弄清楚
回顧一下運算子的強制型轉
從另一個角度看如何利用它們的特性
從一個在很多框架中常用的方法看看
創造一個新的函數叫作 greet.
他需要用name當參數
做的事很簡單 console.log('Hello' + name), 然後呼叫greet
程式碼如下:
function greet(name) {
console.log("Hello " + name);
}
greet("Jimmy");
我傳入我的名字 Jimmy
好的,在 Console 中執行看看
但如果我呼叫greet但沒有參數呢?
程式碼如下:
function greet(name) {
console.log(name);
console.log("Hello " + name);
}
greet();
所以如果我到 Console 中看結果:
不同於很多程式語言 JavaScript 不在乎
這不會丟出錯誤訊息
它會當做 name 沒有東西
結果是我們預期的,對吧?
undefined
因為當函數被呼叫時發生什麼事?
一個新的執行環境被創造 然後這個變數 name 在被執行(呼叫)時被創造
是在函數內被創造,雖然傳入的值是在呼叫時才知道 但這個變數在記憶體已經被設定為 undefined
所以 JavaScript 忽略了
我不用參數呼叫這個函數 然後覺得這很OK
加號運算子將 undefined 強制轉型成字串 'undefined'
所以在 Console 中最終結果為:
因為我們已經知道運算子和強制型轉如何運作
但我們該怎麼辦?
如果我想要一個預設值給這個參數呢?
你會看到有個很棒的方法設定預設值,
程式碼如下:
function greet(name) {
name = name || "<Your name here>";
console.log("Hello " + name);
}
greet();
在 Console 中看結果:
所以如果沒有東西
如果 undefined, 是函數被呼叫時最終的值
記得運算子只是會回傳值的函數
所以這個 ||
運算子
回傳什麼?
他其實做了很簡單的事情
他不只是回傳 true 或 false
在 Console 中看看 ||
運算子的結果:
這回傳 true.
如果我試 undefined or hello, 它不是回傳 true or false
而是回傳 hello
在這情況下,他回傳可以被強制轉型為 true 的值
因為如果我強制轉型 hello ,一個不是空的字串 它是 true
這就是 ||
運算子回傳的
如果我放 hi 和 hello 回傳 hi,因為他回傳第一個被轉換成 true 的值
所以這是 ||
運算子的特殊行為
如果你傳入兩個可以被轉型成true和false的, 它會回傳第一個被轉型成true的值
1 可以被轉換成 true,
0轉成 false
所以我可以用這個來表示 如果這東西不存在或是空字串或是 null 那就給我預設值(能被運算子強制轉型成 true 的值)
我們在 Console 來看:
看出怎樣運作的嗎?
運算子是會回傳值的函數
回到我們的程式碼:
function greet(name) {
name = name || "<Your name here>";
console.log("Hello " + name);
}
greet();
如果 name 是 undefined,或空字串或 null, 那這個 ||
函數、這個 ||
運算子
會回傳預設值給等號運算子
所以 ||
運算子會在 =
運算子之前執行,
因為優先性 指派(等號)運算子的優先性比 ||
運算子低,所以 ||
運算子先執行
如果這是 undefined 就會回傳預設值
然後等號被執行
在 Console 中的結果為:
如果我同時呼叫 greet 兩次,
程式碼如下:
function greet(name) {
name = name || "<Your name here>";
console.log("Hello " + name);
}
greet("Jimmy");
greet();
當 Jimmy 被傳入,這會是true 因為這不是空字串或 undefined, 所以 Jimmy 這個字串會強制轉型為true
這就是 ||
運算子會回傳的
所以 name 會被設為 Tony
我們到 Console 中看結果:
我可以用if陳述句來設定,但會比較多行程式
這很簡潔
當你瞭解之後,可以很清楚讓你閱讀程式碼
你仍然需要注意 0
如果呼叫 greet 時我將 0 當作參數傳入,
程式碼如下:
function greet(name) {
name = name || "<Your name here>";
console.log("Hello " + name);
}
greet(0);
0 會被轉換成false
所以我會得到預設值
所以你需要注意 0
然而,這是特例
在大多時候設預設值是很好的
在 JavaScript 中可以做的很簡潔