在開發過程中,對於某些API在現有的JavaScript執行時環境不支援的時候,我們大都會採用加入polyfill來解決這個問題。但有些時候我們可能需要知道現在某個API到底是否為執行時環境所原生支援,還是polyfill程式碼支援的。今天在學習Vue 2.X版本的原始碼時,就發現了Vue中也有用來檢測一個函式是否為執行時原生支援。
function isNative (Ctor) {
return typeof Ctor === `function` && /native code/.test(Ctor.toString())
}
注意:上述程式碼是我去除Vue中有關於(flow)型別宣告資訊後所得
首先,檢測要被檢測者是否是函式型別,然後會檢測這個被檢測的函式toString之後的字串中是否帶有native code
字眼,如果符合這兩個條件,那麼說明被檢測者是一個當前JavaScript執行時原生支援的函式。
有些人可能會問:為什麼要檢測這個被檢測的函式toString之後的字串中是否帶有native code
字眼,為此我去看了ECMA-262最新規範,很遺憾我沒有找到依據,所以我只能退而求其次去看了MDN和MSDN,看看上面怎麼說。
MDN上在關於Function.prototype.toString()一章上是這麼說的:
If the
toString()
method is called onbuilt-in
function objects or a function created byFunction.prototype.bind
,toString()
returns a native function string which looks like
"function () { [native code] }"
義譯一下就是說:
如果
toString()
方法是由內建函式
(即JavaScript自帶函式)或者是一個經過呼叫Function.prototype.bind
方法後返回的繫結了上下文的函式 所呼叫時,返回的結果就是
"function () { [native code] }"
微軟MSDN上關於toString Method (Object) (JavaScript)一章中是這麼說的:
The toString method is a member of all built-in JavaScript objects. How it behaves depends on the object type:
Object | Behavior |
---|---|
Array | Elements of an Array are converted to strings. The resulting strings are concatenated, separated by commas. |
Boolean | If the Boolean value is true, returns “true “. Otherwise, returns “false “. |
Date | Returns the textual representation of the date. |
Error | Returns a string containing the associated error message. |
Function | Returns a string of the following form, where functionname is the name of the function whose toString method was called:
|
Number | Returns the textual representation of the number. |
String | Returns the value of the String object. |
Default | Returns "[object objectname]" , where objectname is the name of the object type. |
可以看到在內建物件並且型別為Function
時,呼叫toString()
時,返回的也是:
"function functionname( ) { [native code] }"
結論:當一個物件為JavaScript執行時
build-in object
(內建物件),並且型別為Function
型別時,對其呼叫toString()
方法後,返回的結果字串就是如下:
"function functionname( ) { [native code] }"
所以我們可以根據這一特性來得出如何去檢查一個函式是否為JavaScript執行時環境內建函式