JavaScript中判断原生函数的两个示例

简介: 原文链接: Detect if a Function is Native Code with JavaScript原文日期: 2014-08-17翻译日期: 2014-08-20翻译人员: 铁锚我总是经常碰到需要检查某个function是否是原生代码的情况  —— 这是功能测试中一个很重要的内容: 函数是浏览器内置支持的,还是通过第三方类库模拟的。
原文链接:  Detect if a Function is Native Code with JavaScript
原文日期: 2014-08-17
翻译日期: 2014-08-20
翻译人员: 铁锚

我总是经常碰到需要检查某个function是否是原生代码的情况  —— 这是功能测试中一个很重要的内容: 函数是浏览器内置支持的,还是通过第三方类库模拟的。要检测这一点,最简单的办法当然是判断函数的 toString 方法返回的值啦。

JavaScript代码

判断函数是否是原生方法其实相当简单:
// 判断是否原生函数
function isNative(fn) {
    // 示例:
    // alert.toString()
    // "function alert() { [native code] }"
    // '' + fn 利用了js的隐式类型转换.
    return (/\{\s*\[native code\]\s*\}/).test('' + fn);
}

将函数转换为字符串表示的形式,并且执行正则匹配,这就是实现的原理。

升级版,Update!

Lodash 的作者 John-David Dalton 分享了 一个更好的处理方法:
;(function() {

  // 取得Object的toString方法,用于处理传入参数value的内部(internal) `[[Class]]`
  var toString = Object.prototype.toString;
  
  // 取得原始的Function的toString方法,用于处理functions的反编译代码
  var fnToString = Function.prototype.toString;
  
  // 用于检测 宿主对象构造器(host constructors), 
  // (Safari > 4; 真的输出特定的数组,really typed array specific)
  var reHostCtor = /^\[object .+?Constructor\]$/;

  // 使用RegExp将常用的native方法编译为正则模板.
  // 使用 `Object#toString` 是因为一般他不会被污染
  var reNative = RegExp('^' +
    // 将 `Object#toString` 强转为字符串
    String(toString)
    // 对所有正则表达式相关的特殊字符进行转义
    .replace(/[.*+?^${}()|[\]\/\\]/g, '\\$&')
    // 为了保持模板的通用性,将 `toString` 替换为 `.*?`
    // 将`for ...`之类的字符替换,兼容Rhino等环境,因为他们会有额外的信息,如方法的参数数量.
    .replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?')
    // 结束符
    + '$'
    );
  
  function isNative(value) {
    // 判断 typeof
    var type = typeof value;
    return type == 'function'
      // 使用 `Function#toString`原生方法来调用,
      // 而不是 value 自己的 `toString` 方法,
      // 以免被伪造所欺骗.
      ? reNative.test(fnToString.call(value))
      // 如果type 不是'function', 
      // 则需要检查宿主对象(host object)的情形, 
      // 因为某些(浏览器)环境会将 typed arrays 之类的东西当作DOM方法
      // 此时可能不匹配标准的Native正则模式
      : (value && type == 'object' && reHostCtor.test(toString.call(value))) || false;
  };
  
  // 可以将 isNative 赋值给你想要的变量/对象
  window.isNative = isNative;
}());

测试代码:
isNative(isNative)                  //false
isNative(alert)                        //true
window.isNative(window.isNative) //false
window.isNative(window.alert)       //true
window.isNative(String.toString)    //true


目录
相关文章
|
16天前
|
JSON JavaScript 前端开发
JavaScript原生代码处理JSON的一些高频次方法合集
JavaScript原生代码处理JSON的一些高频次方法合集
|
21天前
|
JavaScript
变量和函数提升(js的问题)
变量和函数提升(js的问题)
|
21天前
|
JavaScript
常见函数的4种类型(js的问题)
常见函数的4种类型(js的问题)
11 0
|
21天前
|
JavaScript
写一个函数将N组<>(包含开始和结束),进行组合,并输出组合结果 (js)
写一个函数将N组<>(包含开始和结束),进行组合,并输出组合结果 (js)
9 0
|
1月前
|
自然语言处理 JavaScript 网络架构
js开发:请解释什么是ES6的箭头函数,以及它与传统函数的区别。
ES6的箭头函数以`=>`定义,简化了函数写法,具有简洁语法和词法作用域的`this`。它无`arguments`对象,不能用作构造函数,不支持`Generator`,且不改变`this`、`super`、`new.target`绑定。适用于简短表达式,常用于异步编程和高阶函数。
18 5
|
16天前
|
JavaScript 算法
原生JS完成“一对一、一对多”矩形DIV碰撞检测、碰撞检查,通过计算接触面积(重叠覆盖面积)大小来判断接触对象DOM
原生JS完成“一对一、一对多”矩形DIV碰撞检测、碰撞检查,通过计算接触面积(重叠覆盖面积)大小来判断接触对象DOM
|
2天前
|
JavaScript 前端开发 UED
深入解析JavaScript原生操作DOM技术
【4月更文挑战第22天】本文深入探讨JavaScript原生DOM操作技术,包括使用`getElement*`方法和CSS选择器获取元素,借助`createElement`与`appendChild`动态创建及插入元素,修改元素内容、属性和样式,以及删除元素。通过掌握这些技术,开发者能实现页面动态交互,但应注意避免过度操作DOM以优化性能和用户体验。
|
8天前
|
缓存 JavaScript 前端开发
js的入口函数,入口函数的作用
js的入口函数,入口函数的作用
14 4
|
16天前
|
JavaScript
【归总】原生js操作浏览器hash、url参数参数获取/修改方法合集
【归总】原生js操作浏览器hash、url参数参数获取/修改方法合集
|
23天前
|
存储 前端开发 JavaScript
JavaScript如何封装一些常见的函数来提高工作效率
通过封装这些常见函数,你可以在项目中重复使用,提高代码的复用性和工作效率。这些函数包括获取元素、发起Ajax请求、处理本地存储、日期格式化、定时器等功能,可以在不同场景中减少重复的代码编写。
7 0
JavaScript如何封装一些常见的函数来提高工作效率