教你如何檢查一個函式是否為JavaScript執行時環境內建函式

RIOLI發表於2018-04-07

在開發過程中,對於某些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 on built-in function objects or a function created by Function.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:

function functionname( ) { [native code] }

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執行時環境內建函式

相關文章