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 相关文章推荐
img标签中onerror用法
Aug 13 Javascript
Confirmer JQuery确认对话框组件
Jun 09 Javascript
浅谈Javascript中匀速运动的停止条件
Dec 19 Javascript
jQuery超酷平面式时钟效果代码分享
Mar 30 Javascript
后端接收不到AngularJs中$http.post发送的数据原因分析及解决办法
Jul 05 Javascript
bootstrap模态框垂直居中效果
Dec 03 Javascript
JavaScript中for循环的几种写法与效率总结
Feb 03 Javascript
jQuery获取单选按钮radio选中值与去除所有radio选中状态的方法
May 20 jQuery
BackBone及其实例探究_动力节点Java学院整理
Jul 14 Javascript
30分钟快速入门掌握ES6/ES2015的核心内容(下)
Apr 18 Javascript
一文快速详解前端框架 Vue 最强大的功能
May 21 Javascript
JS判断数组四种实现方法详解
Jun 29 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
ThinkPHP CURD方法之order方法详解
2014/06/18 PHP
跟我学Laravel之快速入门
2014/10/15 PHP
基于PHP的微信公众号的开发流程详解
2020/08/07 PHP
非常不错的一个javascript 类
2006/11/07 Javascript
jQuery(1.6.3) 中css方法对浮动的实现缺陷分析
2011/09/09 Javascript
通过jQuery源码学习javascript(二)
2012/12/27 Javascript
js创建子窗口并且回传值示例代码
2013/07/02 Javascript
浅析Node在构建超媒体API中的作用
2014/07/30 Javascript
js对字符的验证方法汇总
2015/02/04 Javascript
JQuery select(下拉框)操作方法汇总
2015/04/15 Javascript
Javascript中arguments和arguments.callee的区别浅析
2015/04/24 Javascript
jquery自定义表单验证插件
2016/10/12 Javascript
JS访问DOM节点方法详解
2016/11/29 Javascript
html判断当前页面是否在iframe中的实例
2016/11/30 Javascript
jquery DataTable实现前后台动态分页
2017/06/17 jQuery
jQuery使用bind函数实现绑定多个事件的方法
2017/10/11 jQuery
vue实现简单的MVVM框架
2018/08/05 Javascript
React中使用async validator进行表单验证的实例代码
2018/08/17 Javascript
微信小程序实现的一键拨号功能示例
2019/04/24 Javascript
JavaScript设计模式--简单工厂模式定义与应用案例详解
2020/05/23 Javascript
动态创建类实例代码
2009/10/07 Python
python实现推箱子游戏
2020/03/25 Python
梅尔倒谱系数(MFCC)实现
2019/06/19 Python
python自动化测试之如何解析excel文件
2019/06/27 Python
在PyCharm的 Terminal(终端)切换Python版本的方法
2019/08/02 Python
将python字符串转化成长表达式的函数eval实例
2020/05/11 Python
Python中无限循环需要什么条件
2020/05/27 Python
达拉斯牛仔官方商店:Dallas Cowboys Pro Shop
2018/02/10 全球购物
外贸员简历中的自我评价
2014/03/04 职场文书
预备党员自我批评思想汇报
2014/10/10 职场文书
习近平在党的群众路线教育实践活动总结大会上的讲话全文
2014/10/25 职场文书
运动会闭幕词
2015/01/28 职场文书
幼儿园工作总结2015
2015/04/01 职场文书
助学金申请书该怎么写?
2019/07/16 职场文书
CSS实现隐藏搜索框功能(动画正反向序列)
2021/07/21 HTML / CSS
Python 中的Sympy详细使用
2021/08/07 Python