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 相关文章推荐
jquery做的一个简单的屏幕锁定提示框
Mar 26 Javascript
jQuery toggleClass应用实例(附效果图)
Apr 06 Javascript
JavaScript AJAX之惰性载入函数
Aug 27 Javascript
JQuery boxy插件在IE中边角图片不显示问题的解决
May 20 Javascript
莱鸟介绍window.print()方法
Jan 06 Javascript
javascript实现任务栏消息提示的简单实例
May 31 Javascript
基于JS实现回到页面顶部的五种写法(从实现到增强)
Sep 03 Javascript
vee-validate vue 2.0自定义表单验证的实例
Aug 28 Javascript
angularJS实现不同视图同步刷新详解
Oct 09 Javascript
JS使用Dijkstra算法求解最短路径
Jan 17 Javascript
vue2路由基本用法实例分析
Mar 06 Javascript
vue实现用户长时间不操作自动退出登录功能的实现代码
Jul 23 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
2020最新CPU的性能排名
2020/04/02 数码科技
IIS安装Apache伪静态插件的具体操作图文
2013/07/01 PHP
PHP使用Mysqli类库实现完美分页效果的方法
2016/04/07 PHP
php使用preg_match()函数验证ip地址的方法
2017/01/07 PHP
PHP+MySQL使用mysql_num_rows实现模糊查询图书信息功能
2018/05/31 PHP
jquery DOM操作 基于命令改变页面
2010/05/06 Javascript
javascript 子窗体父窗体相互传值方法
2010/05/31 Javascript
js报错 Object doesn't support this property or method的原因分析
2011/03/31 Javascript
javascript高级程序设计第二版第十二章事件要点总结(常用的跨浏览器检测方法)
2012/08/22 Javascript
JQueryEasyUI Layout布局框架的使用
2013/04/08 Javascript
鼠标移到导航当前位置的LI变色处于选中状态
2013/08/23 Javascript
jquery事件重复绑定的快速解决方法
2014/01/03 Javascript
javascript判断office版本示例
2014/04/11 Javascript
jquery加载图片时以淡入方式显示的方法
2015/01/14 Javascript
javascript中sort()的用法实例分析
2015/01/30 Javascript
js实现数字每三位加逗号的方法
2015/02/05 Javascript
JavaScript中toString()方法的使用详解
2015/06/05 Javascript
javascript正则表达式总结
2016/02/29 Javascript
详解webpack解惑:require的五种用法
2017/06/09 Javascript
解决layui-open关闭自身窗口的问题
2019/09/10 Javascript
vue调用语音播放的方法
2019/09/27 Javascript
Python编程中的文件操作攻略
2015/10/16 Python
python微信跳一跳系列之棋子定位颜色识别
2018/02/26 Python
Python 3.x 安装opencv+opencv_contrib的操作方法
2018/04/02 Python
在Python中使用gRPC的方法示例
2018/08/08 Python
Django restframework 源码分析之认证详解
2019/02/22 Python
python实现二维数组的对角线遍历
2019/03/02 Python
Pytorch转keras的有效方法,以FlowNet为例讲解
2020/05/26 Python
Python 多线程C段扫描、检测 Ping扫描脚本的实现
2020/09/03 Python
HTML5 history新特性pushState、replaceState及两者的区别
2015/12/26 HTML / CSS
Lenox官网:精美的瓷器&独特的礼品
2017/02/12 全球购物
英国家居用品和床上用品零售商:P&B Home
2020/01/16 全球购物
IMPORT的选项IGNORE有什么作用?缺省是什么设置?
2015/09/17 面试题
电脑租赁公司创业计划书
2014/01/08 职场文书
初中语文教学随笔
2015/08/15 职场文书
Android超详细讲解组件ScrollView的使用
2022/03/31 Java/Android