JavaScript中判断原生函数检查function是否是原生代码


Posted in Javascript onSeptember 09, 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 相关文章推荐
javascript静态的url如何传递
May 03 Javascript
基于jquery的动态创建表格的插件
Apr 05 Javascript
点击按钮自动加关注的代码(sina微博/QQ空间/人人网/腾讯微博)
Jan 02 Javascript
JavaScript的Backbone.js框架的一些使用建议整理
Feb 14 Javascript
js获取Html元素的实际宽度高度的方法
May 19 Javascript
微信小程序分页加载的实例代码
Jul 11 Javascript
微信小程序 本地图片按照屏幕尺寸处理
Aug 04 Javascript
canvas绘制爱心的几种方法总结(推荐)
Oct 31 Javascript
详解微信小程序网络请求接口封装实例
May 02 Javascript
微信小程序授权登录解决方案的代码实例(含未通过授权解决方案)
May 10 Javascript
JavaScript中Dom操作实例详解
Jul 08 Javascript
vue3.0封装轮播图组件的步骤
Mar 04 Vue.js
三种取消选中单选框radio的方法
Sep 09 #Javascript
使用JQuery库提供的扩展功能实现自定义方法
Sep 09 #Javascript
JQuery 给元素绑定click事件多次执行的解决方法
Sep 09 #Javascript
一个实用的图片切换支持点击切换和自动轮播
Sep 09 #Javascript
用JavaScript实现用一个DIV来包装文本元素节点
Sep 09 #Javascript
点击button获取text内容并改变样式的js实现
Sep 09 #Javascript
js 数组去重的四种实用方法
Sep 09 #Javascript
You might like
全国FM电台频率大全 - 9 上海市
2020/03/11 无线电
一个简单的php实现的MySQL数据浏览器
2007/03/11 PHP
php产生随机数的两种方法实例代码 输出随机IP
2011/04/08 PHP
PHP Warning: PHP Startup: Unable to load dynamic library \ D:/php5/ext/php_mysqli.dll\
2012/06/17 PHP
PHP计算2点经纬度之间的距离代码
2013/08/12 PHP
从零开始学YII2框架(一)通过Composer安装Yii2框架
2014/08/20 PHP
php实现36进制与10进制转换功能示例
2017/01/10 PHP
实现php删除链表中重复的结点
2018/09/27 PHP
prototype 1.5 & scriptaculous 1.6.1 学习笔记
2006/09/07 Javascript
一个刚完成的layout(拖动流畅,不受iframe影响)
2007/08/17 Javascript
javascript当onmousedown、onmouseup、onclick同时应用于同一个标签节点Element
2010/01/05 Javascript
基于jquery跨浏览器显示的file上传控件
2011/10/24 Javascript
jQuery中[attribute=value]选择器用法实例
2014/12/31 Javascript
详解JavaScript操作HTML DOM的基本方式
2015/10/21 Javascript
jQuery+AJAX实现遮罩层登录验证界面(附源码)
2020/09/13 Javascript
js图片轮播效果实现代码
2020/04/18 Javascript
jQuery简单实现提交数据出现loading进度条的方法
2016/03/29 Javascript
Angular企业级开发——MVC之控制器详解
2017/02/20 Javascript
vue 全局环境切换问题
2019/10/27 Javascript
node.js中事件触发器events的使用方法实例分析
2019/11/23 Javascript
[39:46]完美世界DOTA2联赛PWL S2 LBZS vs Rebirth 第二场 11.25
2020/11/25 DOTA
python requests post多层字典的方法
2018/12/27 Python
python快排算法详解
2019/03/04 Python
Django urls.py重构及参数传递详解
2019/07/23 Python
Python turtle绘画象棋棋盘
2019/08/21 Python
python中pivot()函数基础知识点
2021/01/03 Python
CSS3中设置3D变形的transform-style属性详解
2016/05/23 HTML / CSS
iframe跨域的几种常用方法
2019/11/11 HTML / CSS
智能室内花园:Click & Grow
2021/01/29 全球购物
党员年终民主评议的自我评价
2013/11/05 职场文书
公共场所标语
2014/06/30 职场文书
城管个人总结
2015/02/28 职场文书
学习杨善洲同志先进事迹心得体会
2016/01/23 职场文书
升职自荐书
2019/05/09 职场文书
Linux系统下安装PHP7.3版本
2021/06/26 PHP
Javascript中Microtask和Macrotask鲜为人知的知识点
2022/04/02 Javascript