教你如何检查一个函数是否为JavaScript运行时环境内建函数
在开发过程中,对于某些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 thetoString()
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: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运行时环境内建函数