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中eq和get的区别与使用方法
Apr 14 Javascript
javascript圆盘抽奖程序实现原理和完整代码例子
Jun 03 Javascript
js实现横向百叶窗效果网页切换动画效果的方法
Mar 02 Javascript
AngularJS在IE下取数据总是缓存问题的解决方法
Aug 05 Javascript
最常见的左侧分类菜单栏jQuery实现代码
Nov 28 Javascript
JS实现拖拽的方法分析
Dec 20 Javascript
angular.js+node.js实现下载图片处理详解
Mar 31 Javascript
Vue实现双向数据绑定
May 03 Javascript
JS实现元素上下左右移动效果
Oct 18 Javascript
node基于puppeteer模拟登录抓取页面的实现
May 09 Javascript
浅谈Node.js 中间件模式
Jun 12 Javascript
JavaScript实现星级评价效果
May 17 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中如何实现常用邮箱的基本判断
2014/01/07 PHP
cakephp打印sql语句的方法
2015/02/13 PHP
PHP的Yii框架中View视图的使用进阶
2016/03/29 PHP
用JavaScript事件串连执行多个处理过程的方法
2007/03/09 Javascript
javascript来定义类的规范小结
2010/11/19 Javascript
jQuery中使用Ajax获取JSON格式数据示例代码
2013/11/26 Javascript
instanceof和typeof运算符的区别详解
2014/01/06 Javascript
jQuery操作DOM之获取表单控件的值
2015/01/23 Javascript
JS实现简洁、全兼容的拖动层实例
2015/05/13 Javascript
javascript针对cookie的基本操作实例详解
2015/11/30 Javascript
javascript实现全角转半角的方法
2016/01/23 Javascript
JQuery为元素添加样式的实现方法
2016/07/20 Javascript
JavaScript中的对象和原型(一)
2016/08/12 Javascript
微信小程序 使用picker封装省市区三级联动实例代码
2016/10/28 Javascript
canvas红包照片实例分享
2017/02/28 Javascript
AngularJS封装$http.post()实例详解
2017/05/06 Javascript
原生js二级联动效果
2017/06/20 Javascript
Webpack框架核心概念(知识点整理)
2017/12/22 Javascript
jquery 获取索引值在一定范围的列表方法
2018/01/25 jQuery
小程序实现列表删除功能
2018/10/30 Javascript
Node.js 实现远程桌面监控的方法步骤
2019/07/02 Javascript
基于JavaScript实现简单的轮播图
2021/03/03 Javascript
Python中文字符串截取问题
2015/06/15 Python
实例解析Python中的__new__特殊方法
2016/06/02 Python
Django 添加静态文件的两种实现方法(必看篇)
2017/07/14 Python
python3+requests接口自动化session操作方法
2018/10/13 Python
Selenium定时刷新网页的实现代码
2018/10/31 Python
python访问hdfs的操作
2020/06/06 Python
Appium+Python实现简单的自动化登录测试的实现
2021/01/26 Python
利用css3制作3D样式按钮实现代码
2013/03/18 HTML / CSS
复古风格的女装和装饰品:ModCloth
2017/12/29 全球购物
新手上路标语
2014/06/20 职场文书
“学党章、守党纪、讲党规”学习心得体会
2016/01/14 职场文书
写自招自荐信的绝招!
2019/04/19 职场文书
教你怎么用Python selenium操作浏览器对象的基础API
2021/06/23 Python
Python使用DFA算法过滤内容敏感词
2022/04/22 Python