JS code that determines whether the method is native

  • 2020-03-29 23:41:54
  • OfStack

The trend in browsers is to add more and more objects, like workers, as well as new methods for older objects. The first step in compatibility is to check if they exist, and if they don't, add your own compatibility code. The problem is, there are libraries that do this for you, and sometimes they don't, and sometimes they do it, but they don't meet the standard. So typeof array.prototype.map === "function" may not be enough. This is where the isNative method comes in.

The version I've been using, written by myself:

var isNative = function(method){//Determines whether it is a native method
      return !! method && (/{s*[native code]s*}/.test(method+"") ||
          /{s*/* source code not available */s*}/.test(method+""));//This is for opera9.x

But the world is so big, there must be some research on this issue. The following version of Diego Perini points out that safari's toString value for native methods is also a misfit:

var isNative = function(object, method) {
    return object && method in object &&
      typeof object[method] != 'string' &&
      // IE & W3C browser return "[native code]"
      // Safari < = 2.0.4 will return "[function]"
      (/{s*[native code]s*}|^[function]$/).test(object[method]);

It has one more argument than my version, and can specify the method of that native object, but one argument is not related to two arguments, it just shows that we are still some way from being perfect. Even if you take the union of these two functions, it's probably not the right set.

Of course, this is not a question of [native code] or source code not available or [function], because it is easy to copy various methods and objects in javascript. For example, the following code can successfully fool the detection code.

window.test = {
  toString: function() {
    return '[function]';
isNative(window, 'test'); // true

Finally I found this from nwmathers:

var isNative = (function() {
   var s = (window.open + '').replace(/open/g, '');
   return function(object, method) {
     var m = object ? object[method] : false, r = new RegExp(method, 'g');
     return !!(m && typeof m != 'string' && s === (m + '').replace(r, ''));

Related articles: