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版三级联动select示例
Jul 04 Javascript
jQuery实现移动 和 渐变特效的点击事件
Feb 26 Javascript
javascript动态创建表格及添加数据实例详解
May 13 Javascript
js实现文本框只允许输入数字并限制数字大小的方法
Aug 19 Javascript
整理Javascript函数学习笔记
Dec 01 Javascript
js正则表达式最长匹配(贪婪匹配)和最短匹配(懒惰匹配)用法分析
Dec 27 Javascript
微信小程序之数据双向绑定与数据操作
May 12 Javascript
JS简单实现自定义右键菜单实例
May 31 Javascript
浅谈JavaScript作用域和闭包
Sep 18 Javascript
深入浅析Vue中的Prop
Jun 10 Javascript
Node.js系列之连接DB的方法(3)
Aug 30 Javascript
js实现移动端图片滑块验证功能
Sep 29 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不用递归实现无限分级的例子分享
2014/04/18 PHP
qq登录,新浪微博登录接口申请过程中遇到的问题
2014/07/22 PHP
在Mac OS的PHP环境下安装配置MemCache的全过程解析
2016/02/15 PHP
PHP框架Laravel插件Pagination实现自定义分页
2020/04/22 PHP
简单PHP会话(session)说明介绍
2016/08/21 PHP
阿里对象存储OSS在laravel框架中的使用方法
2019/10/13 PHP
Laravel实现通过blade模板引擎渲染视图
2019/10/25 PHP
通过Javascript读取本地Excel文件内容的代码示例
2014/04/08 Javascript
JavaScript作用域链示例分享
2014/05/27 Javascript
JS版元素周期表实现方法
2015/08/05 Javascript
Vue中定义全局变量与常量的各种方式详解
2017/08/23 Javascript
详解Node使用Puppeteer完成一次复杂的爬虫
2018/04/18 Javascript
在微信小程序中渲染HTML内容的方法示例
2018/09/28 Javascript
浅谈vuex中store的命名空间
2019/11/08 Javascript
vue制作toast组件npm包示例代码
2020/10/29 Javascript
用vite搭建vue3应用的实现方法
2021/02/22 Vue.js
Python最火、R极具潜力 2017机器学习调查报告
2017/12/11 Python
python编程通过蒙特卡洛法计算定积分详解
2017/12/13 Python
Python3.6基于正则实现的计算器示例【无优化简单注释版】
2018/06/14 Python
PyCharm配置mongo插件的方法
2018/11/30 Python
Python中类的创建和实例化操作示例
2019/02/27 Python
Python实现的矩阵转置与矩阵相乘运算示例
2019/03/26 Python
python对象与json相互转换的方法
2019/05/07 Python
500行Python代码打造刷脸考勤系统
2019/06/03 Python
8种用Python实现线性回归的方法对比详解
2019/07/10 Python
django一对多模型以及如何在前端实现详解
2019/07/24 Python
python 监控logcat关键字功能
2020/09/04 Python
html5时钟实现代码
2010/10/22 HTML / CSS
介绍一下SOA和SOA的基本特征
2016/02/24 面试题
出纳岗位职责
2013/11/09 职场文书
饲料采购员岗位职责
2013/12/19 职场文书
汉语言文学专业求职信
2014/06/19 职场文书
2014年精神文明工作总结
2014/12/23 职场文书
vue-element-admin项目导入和导出的实现
2021/05/21 Vue.js
go goroutine 怎样进行错误处理
2021/07/16 Golang
SpringBoot详解执行过程
2022/07/15 Java/Android