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 相关文章推荐
js/ajax跨越访问-jsonp的原理和实例(javascript和jquery实现代码)
Dec 27 Javascript
原生js实现shift/ctrl/alt按键的获取
Apr 08 Javascript
JQuery Tips相关(1)----关于$.Ready()
Aug 14 Javascript
jquery delay()介绍及使用指南
Sep 02 Javascript
JS小游戏之仙剑翻牌源码详解
Sep 25 Javascript
jquery+php实现滚动的数字特效
Nov 29 Javascript
根据Bootstrap Paginator改写的js分页插件
Dec 25 Javascript
微信小程序 常用工具类详解及实例
Feb 15 Javascript
mui上拉加载功能实例详解
Apr 13 Javascript
angular.js + require.js构建模块化单页面应用的方法步骤
Jul 19 Javascript
javascript+html5+css3自定义弹出窗口效果
Oct 26 Javascript
使用JS前端技术实现静态图片局部流动效果
Aug 05 Javascript
三种取消选中单选框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
PHP中获取变量的变量名的一段代码的bug分析
2011/07/07 PHP
php代码中使用换行及(\n或\r\n和br)的应用
2013/02/02 PHP
PHP回溯法解决0-1背包问题实例分析
2015/03/23 PHP
laravel在中间件内生成参数并且传递到控制器中的2种姿势
2019/10/15 PHP
js ondocumentready onmouseover onclick onmouseout 样式
2010/07/22 Javascript
javascript闭包的理解和实例
2010/08/12 Javascript
本地图片预览(支持IE6/IE7/IE8/Firefox3)经验总结
2013/03/25 Javascript
点击A元素触发B元素的事件在IE8下会识别成A元素
2014/09/04 Javascript
jQuery判断浏览器并动态调整select宽度的方法
2016/03/02 Javascript
微信jssdk在iframe页面失效问题的解决措施
2016/03/03 Javascript
基于javascript实现页面加载loading效果
2020/09/15 Javascript
Ajax和Comet技术总结
2017/02/19 Javascript
JS实现线性表的顺序表示方法示例【经典数据结构】
2017/04/11 Javascript
详解tween.js的使用教程
2017/09/14 Javascript
React通过父组件传递类名给子组件的实现方法
2017/11/13 Javascript
vue实现点击展开点击收起效果
2018/04/27 Javascript
微信小程序实现搜索功能并跳转搜索结果页面
2019/05/18 Javascript
js实现弹窗猜数字游戏
2020/11/26 Javascript
在Python中进行自动化单元测试的教程
2015/04/15 Python
python分治法求二维数组局部峰值方法
2018/04/03 Python
Python基于pandas实现json格式转换成dataframe的方法
2018/06/22 Python
Python使用while循环花式打印乘法表
2019/01/28 Python
python可视化篇之流式数据监控的实现
2019/08/07 Python
Python基于WordCloud制作词云图
2019/11/29 Python
python:目标检测模型预测准确度计算方式(基于IoU)
2020/01/18 Python
python3.6连接mysql数据库及增删改查操作详解
2020/02/10 Python
Python实现淘宝秒杀功能的示例代码
2021/01/19 Python
html5弹跳球示例代码
2013/07/23 HTML / CSS
中国领先的专业演出票务网:永乐票务
2016/08/29 全球购物
英国知名的皮手套品牌:Dents
2016/11/13 全球购物
美国著名的户外用品品牌:L.L.Bean
2018/01/05 全球购物
CHARLES & KEITH澳大利亚官网:新加坡时尚品牌
2019/01/22 全球购物
教师自我评价范例
2013/09/24 职场文书
公司年会搞笑主持词
2014/03/24 职场文书
大学校园餐饮创业计划书
2019/08/07 职场文书
《雀魂PONG☆》4月1日播出 PV角色设定情报
2022/03/20 日漫