JavaScript检查某个function是否是原生代码的方法


Posted in Javascript onAugust 20, 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 使用手册(一)
Sep 23 Javascript
jQuery 美元符冲突的解决方法
Mar 28 Javascript
Extjs TimeField 显示正常时间格式的代码
Jun 28 Javascript
JS Date函数整理方便使用
Oct 23 Javascript
jQuery中data()方法用法实例
Dec 27 Javascript
很棒的js选项卡切换效果
Jul 15 Javascript
深入分析javascript中console命令
Aug 14 Javascript
AngularJS学习笔记(三)数据双向绑定的简单实例
Nov 08 Javascript
JS获得一个对象的所有属性和方法实例
Feb 21 Javascript
详解Node.js 命令行程序开发教程
Jun 07 Javascript
Vue实现移动端页面切换效果【推荐】
Nov 13 Javascript
JavaScript动态生成表格的示例
Nov 02 Javascript
使用时间戳解决ie缓存的问题
Aug 20 #Javascript
js中使用replace方法完成某个字符的转换
Aug 20 #Javascript
js 动态修改css文件用到了cssRule
Aug 20 #Javascript
jquery实现在页面加载的时自动为日期插件添加当前日期
Aug 20 #Javascript
js匿名函数的调用示例(形式多种多样)
Aug 20 #Javascript
javascript对中文按照拼音排序代码
Aug 20 #Javascript
JS辨别访问浏览器判断是android还是ios系统
Aug 19 #Javascript
You might like
PHP 上传文件的方法(类)
2009/07/30 PHP
PHP解密Unicode及Escape加密字符串
2015/05/17 PHP
PHP生成可点击刷新的验证码简单示例
2016/05/13 PHP
thinkphp框架无限级栏目的排序功能实现方法示例
2020/03/29 PHP
Prototype 学习 工具函数学习($方法)
2009/07/12 Javascript
jQuery UI Datepicker length为空或不是对象错误的解决方法
2010/12/19 Javascript
js页面跳转的常用方法整理
2013/10/18 Javascript
鼠标滑在标题上显示图片的JS代码
2013/11/19 Javascript
javascript针对不确定函数的执行方法
2015/12/16 Javascript
jQuery中Chosen三级联动功能实例代码
2017/03/07 Javascript
用nodeJS搭建本地文件服务器的几种方法小结
2017/03/16 NodeJs
详解微信小程序 通过控制CSS实现view隐藏与显示
2017/05/24 Javascript
详解如何构建Angular项目目录结构
2017/07/13 Javascript
在页面中引入js的两种方法(推荐)
2017/08/29 Javascript
nodejs async异步常用函数总结(推荐)
2017/11/17 NodeJs
jQuery 改变P标签文本值方法
2018/02/24 jQuery
Python的ORM框架SQLAlchemy入门教程
2014/04/28 Python
python实现查找excel里某一列重复数据并且剔除后打印的方法
2015/05/26 Python
Python正则替换字符串函数re.sub用法示例
2017/01/19 Python
Python实现发送QQ邮件的封装
2017/07/14 Python
快速入门python学习笔记
2017/12/06 Python
Python字典中的值为列表或字典的构造实例
2019/12/16 Python
python argparse传入布尔参数false不生效的解决
2020/04/20 Python
如何设置PyCharm中的Python代码模版(推荐)
2020/11/20 Python
python 发送邮件的示例代码(Python2/3都可以直接使用)
2020/12/03 Python
是否有自动比较结构的方法
2015/06/03 面试题
写出SQL四条最基本的数据操作语句(DML)
2012/12/12 面试题
.net工程师笔试题
2012/06/09 面试题
介绍一下XMLHttpRequest对象的常用方法和属性
2013/05/24 面试题
十八大报告观后感
2014/01/28 职场文书
先进集体事迹材料
2014/02/17 职场文书
2014年两会学习心得范例
2014/03/17 职场文书
团员个人总结
2015/02/26 职场文书
工作保证书怎么写
2015/02/28 职场文书
2015年社区科普工作总结
2015/05/13 职场文书
MySQL数据库10秒内插入百万条数据的实现
2021/11/01 MySQL