keywords:undefined
,undeclared
,dependency injection
型別的值
- 變數沒有型別,值才有型別,變數在不同時間點上可以持有任何的值
- JavaScript 不會堅持一個變數必須永遠保持與其初始型別相同的值
typeof 功能是在問『 該變數中的那個值是什麼型別 ? 』
有趣的例子:let a = 99; typeof typeof a; // string 恩!? 分解動作: 1. typeof a; // number 2. typeof number; // string
未定義 ( undefined ) VS. 未宣告 ( undeclared )
- undefined 表示在可取用的範疇中已宣告了變數,只是當下沒有其他值
undeclared 表示在可取用的範疇中,從未正式宣告被使用的變數
看看例子:let a; a; // undefined b; // ReferenceError: b is not defined
🚩 undefined 及 is not defined 是不同的兩回事
🚩 undefined 及 is not defined 是不同的兩回事
🚩 undefined 及 is not defined 是不同的兩回事
∵ It's very significant ∴ three times. 😏But how about this:
let a ; typeof a; // undefined typeof b; // undefined 恩!? 說好的不同的兩回事呢?
原本應該要跳出未宣告提示,但這是 typeof 的一個安全護機制,避免直接讓程式擲出錯誤的安全防護
但是如果這個訊息是 『 b is not declared ( b 沒有宣告 )』那就太好了,這樣就可以減少許多混淆。
typeof Undeclared
儘管如此,這個安全防護是一項實用的特色,因為在執行環境下可能會有多個指令搞 ( script )檔案載入變數
看看例子:
使用的場景像是檢查內建 API 某功能是否存在,防止擲出錯誤if (typeof f1 === 'undefined'){ f1 = function (){...} // f1 不存在所以建立 function ,而不是直接擲出錯誤 }
如果想檢查是否存在某個變數,也可以使用 window 物件試著存取一個不存在的物件特性,並不會擲出 ReferenceError,但應該要避免使用此方法,因為程式碼會在多個 JS 環境中執行 ( ex. 伺服器端為 Node.js ),屆時全域物件不一定叫做 window
window.f1; // undefined f1; // ReferenceError: abc is not defined
開發人員也偏好一種檢查是否有定義,稱為 依存性注入 ( dependency injection ) 的設計模式
先來看非依存性注入的程式碼:
(function() { function showA { console.log('a'); } function f1() { let shower = (typeof showA !== undefined )? showA : function (){...}; let f2 = shower(); //.. } f1(); })();
- 依存性注入的程式碼:
依存注入模式下不會隱含地查驗函式是否已定義,而是要求依存性明確地被傳入function f1 (showA) { let shower = showA || function (){...}; let f2 = shower(); //.. }