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 相关文章推荐
xml文档转换工具,附图表例子(hta)
Nov 17 Javascript
中国地区三级联动下拉菜单效果分析
Nov 15 Javascript
实现只能输入数字的input不用replace方法
Sep 12 Javascript
jquery操作复选框checkbox的方法汇总
Feb 05 Javascript
Three.js学习之Lamber材质和Phong材质
Aug 04 Javascript
Bootstrap在线电子商务网站实战项目5
Oct 14 Javascript
jQuery实现的鼠标滚轮控制图片缩放功能实例
Oct 14 jQuery
详解webpack多页面配置记录
Jan 22 Javascript
浅谈webpack 自动刷新与解析
Apr 09 Javascript
js数组去重的N种方法(小结)
Jun 07 Javascript
JavaScript实现的级联算法示例【省市二级联动功能】
Dec 25 Javascript
详解vue几种主动刷新的方法总结
Feb 19 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使用函数pathinfo()、parse_url()和basename()解析URL
2016/11/25 PHP
Yaf框架封装的MySQL数据库操作示例
2019/03/06 PHP
json 定义
2008/06/10 Javascript
JS 字符串连接[性能比较]
2009/05/10 Javascript
jquery ajax提交表单数据的两种实现方法
2010/04/29 Javascript
基于jquery的修改当前TAB显示标题的代码
2010/12/11 Javascript
关于setInterval、setTimeout在jQuery中的使用注意事项
2011/09/28 Javascript
5种处理js跨域问题方法汇总
2014/12/04 Javascript
jQuery+PHP实现可编辑表格字段内容并实时保存
2015/10/09 Javascript
vue开发心得和技巧分享
2016/10/27 Javascript
js原生Ajax的封装和原理详解
2017/03/11 Javascript
简单谈谈require模块化jquery和angular的问题
2017/06/23 jQuery
vue2.0 路由模式mode="history"的作用
2018/10/18 Javascript
js验证身份证号码记录的方法
2019/04/26 Javascript
pymongo实现多结果进行多列排序的方法
2015/05/16 Python
python中字符串内置函数的用法总结
2018/09/13 Python
详解Python装饰器
2019/03/25 Python
详解python tkinter教程-事件绑定
2019/03/28 Python
Python selenium自动化测试模型图解
2020/04/15 Python
在Anaconda3下使用清华镜像源安装TensorFlow(CPU版)
2020/04/19 Python
从0到1使用python开发一个半自动答题小程序的实现
2020/05/12 Python
解决python 执行sql语句时所传参数含有单引号的问题
2020/06/06 Python
关于python中导入文件到list的问题
2020/10/31 Python
如何通过Python实现RabbitMQ延迟队列
2020/11/28 Python
浅谈html5与APP混合开发遇到的问题总结
2018/03/20 HTML / CSS
微软英国官方网站:Microsoft英国
2016/10/15 全球购物
英国高级百货公司:Harvey Nichols
2017/01/29 全球购物
采用冷却技术的超自然舒适度:GhostBed床垫
2018/09/18 全球购物
党课培训主持词
2014/04/01 职场文书
大学生励志演讲稿
2014/04/25 职场文书
业务内勤岗位职责
2014/04/30 职场文书
大学生撤销处分思想汇报
2014/09/12 职场文书
三八红旗手事迹材料
2014/12/26 职场文书
小学一年级班主任工作经验交流材料
2015/11/02 职场文书
Golang 链表的学习和使用
2022/04/19 Golang
vue生命周期钩子函数以及触发时机
2022/04/26 Vue.js