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


Posted in Javascript onAugust 20, 2014

我总是经常碰到需要检查某个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 相关文章推荐
html下载本地
Jun 19 Javascript
超级给力的JavaScript的React框架入门教程
Jul 02 Javascript
javascript冒泡排序小结
Apr 10 Javascript
js删除数组元素、清空数组的简单方法(必看)
Jul 27 Javascript
node.js请求HTTPS报错:UNABLE_TO_VERIFY_LEAF_SIGNATURE\的解决方法
Dec 18 Javascript
jQuery实现的鼠标滚轮控制图片缩放功能实例
Oct 14 jQuery
微信小程序购物车、父子组件传值及calc的注意事项总结
Nov 14 Javascript
JavaScript常用工具方法封装
Feb 12 Javascript
ES6中Set和Map数据结构,Map与其它数据结构互相转换操作实例详解
Feb 28 Javascript
vue-cli3 取消eslint校验代码的解决办法
Jan 16 Javascript
vue-resource post数据时碰到Django csrf问题的解决
Mar 13 Javascript
vue使用exif获取图片旋转,压缩的示例代码
Dec 11 Vue.js
使用时间戳解决ie缓存的问题
Aug 20 #Javascript
js中使用replace方法完成某个字符的转换
Aug 20 #Javascript
js 动态修改css文件用到了cssRule
Aug 20 #Javascript
jquery实现在页面加载的时自动为日期插件添加当前日期
Aug 20 #Javascript
js匿名函数的调用示例(形式多种多样)
Aug 20 #Javascript
javascript对中文按照拼音排序代码
Aug 20 #Javascript
JS辨别访问浏览器判断是android还是ios系统
Aug 19 #Javascript
You might like
解析PHP对现有搜索引擎的调用
2013/06/25 PHP
php开启openssl的方法
2014/05/15 PHP
CodeIgniter错误mysql_connect(): No such file or directory解决方法
2014/09/06 PHP
Referer原理与图片防盗链实现方法详解
2019/07/03 PHP
jQuery timers计时器简单应用说明
2010/10/28 Javascript
JS中toFixed()方法引起的问题如何解决
2012/11/20 Javascript
jquery入门——事件机制之事件中的冒泡现象示例解释
2020/09/12 Javascript
jquery实现兼容IE8的异步上传文件
2015/06/15 Javascript
jQuery控制li上下循环滚动插件用法实例(附demo源码下载)
2016/05/28 Javascript
jQuery获取file控件中图片的宽高与大小
2016/08/04 Javascript
jQuery内容过滤选择器用法示例
2016/09/09 Javascript
利用Jquery实现几款漂亮实用的时间轴(附示例代码)
2017/02/15 Javascript
JS实现移动端整屏滑动的实例代码
2017/11/10 Javascript
在layui中layer弹出层点击事件无效的解决方法
2019/09/05 Javascript
JS实现音量控制拖动
2020/01/15 Javascript
angular组件间通讯的实现方法示例
2020/05/07 Javascript
原生js实现表格翻页和跳转
2020/09/29 Javascript
[51:14]LGD vs VP 2018国际邀请赛淘汰赛BO3 第一场 8.21
2018/08/22 DOTA
[51:53]完美世界DOTA2联赛决赛日 Inki vs LBZS 第二场 11.08
2020/11/10 DOTA
python监控文件或目录变化
2016/06/07 Python
python导入csv文件出现SyntaxError问题分析
2017/12/15 Python
Python读csv文件去掉一列后再写入新的文件实例
2017/12/28 Python
如何使用python把ppt转换成pdf
2019/06/29 Python
PyQt5多线程刷新界面防假死示例
2019/12/13 Python
pytorch中交叉熵损失(nn.CrossEntropyLoss())的计算过程详解
2020/01/02 Python
Spanx塑身衣官网:美国知名内衣品牌
2017/01/11 全球购物
Hotels.com爱尔兰:全球酒店预订
2017/02/24 全球购物
世界上最大的在线学习和教学市场:Udemy
2017/11/08 全球购物
Hertz荷兰:荷兰和全球租车
2018/01/07 全球购物
单位消防安全制度
2014/01/12 职场文书
幼儿园教师师德师风演讲稿:爱我所爱 无悔青春
2014/09/10 职场文书
永远跟党走演讲稿
2014/09/12 职场文书
2015年小学校长工作总结
2015/05/19 职场文书
2016大一新生军训感言
2015/12/08 职场文书
在MySQL中你成功的避开了所有索引
2022/04/20 MySQL
Python使用MapReduce进行简单的销售统计
2022/04/22 Python