JavaScript检查某个function是否是原生代码的方法

 更新时间:2014年08月20日 17:43:14   投稿:whsnow  
经常碰到需要检查某个function是否是原生代码,要检测这一点,最简单的办法当然是判断函数的 toString 方法返回的值

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

JavaScript代码

判断函数是否是原生方法其实相当简单:

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

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

升级版,Update!

;(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

相关文章

  • javascript面向对象三大特征之封装实例详解

    javascript面向对象三大特征之封装实例详解

    这篇文章主要介绍了javascript面向对象三大特征之封装,简单描述了封装的基本概念、原理,并结合实例形式详细分析了javascript面向对象程序设计中封装的用法与相关操作注意事项,需要的朋友可以参考下
    2019-07-07
  • js实现分享到随页面滚动而滑动效果的方法

    js实现分享到随页面滚动而滑动效果的方法

    这篇文章主要介绍了js实现分享到随页面滚动而滑动效果的方法,实例分析了javascript操作页面元素滚动效果的方法,需要的朋友可以参考下
    2015-04-04
  • JavaScript基于ChatGPT API实现划词翻译浏览器脚本

    JavaScript基于ChatGPT API实现划词翻译浏览器脚本

    最近 GitHub 上有个基于 ChatGPT API 的浏览器脚本,openai-translator, 短时间内 star 冲到了 9.7k,抛开 tauri 是使用 rust 部分,那浏览器部分实现还是比较简单的,今天我们就来手动实现一下
    2023-03-03
  • Email地址加密javascript版

    Email地址加密javascript版

    Email地址加密javascript版...
    2006-08-08
  • JS打印gridview实现原理及代码

    JS打印gridview实现原理及代码

    打印gridview对于一些童鞋们真的是很陌生啊,不过没有关系,因为本文的出现,或让你茅塞顿开,好了话不多说,感兴趣的朋友可以了解下,或许对你学习js高级知识有所帮助
    2013-02-02
  • 浅析Bootstrap缩略图组件与警示框组件

    浅析Bootstrap缩略图组件与警示框组件

    缩略图在网站中最常用的就是产品列表页面,一行显示几张图片,有的在图片底下带有标题、描述内容、按钮等信息。本文给大家介绍Bootstrap缩略图组件与警示框组件,感兴趣的朋友一起学习吧
    2016-04-04
  • HTML5游戏引擎LTweenLite实现的超帅动画效果(附demo源码下载)

    HTML5游戏引擎LTweenLite实现的超帅动画效果(附demo源码下载)

    这篇文章主要介绍了HTML5游戏引擎LTweenLite实现的超帅动画效果,详细分析了LTweenLite的下载,动画效果的实现步骤,并附带完整的demo实例源码供读者下载,需要的朋友可以参考下
    2016-01-01
  • js仿手机页面文件下拉刷新效果

    js仿手机页面文件下拉刷新效果

    这篇文章主要为大家详细介绍了js仿手机页面文件的下拉刷新,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-10-10
  • three.js中物体的灯光与阴影设置

    three.js中物体的灯光与阴影设置

    本文主要介绍了three.js中物体的灯光与阴影设置,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • 微信小程序  TLS 版本必须大于等于1.2问题解决

    微信小程序 TLS 版本必须大于等于1.2问题解决

    这篇文章主要介绍了微信小程序 TLS 版本必须大于等于1.2问题解决的相关资料,需要的朋友可以参考下
    2017-02-02

最新评论