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 相关文章推荐
在chrome浏览器中,防止input[text]和textarea在聚焦时出现黄色边框的解决方法
May 24 Javascript
远离JS灾难css灾难之 js私有函数和css选择器作为容器
Dec 11 Javascript
JavaScript基于ajax编辑信息用法实例
Jul 15 Javascript
JavaScript如何实现对数字保留两位小数一位自动补零
Dec 18 Javascript
Javascript获取统一管理的提示语(message)
Feb 03 Javascript
浅谈JavaScript中的分支结构
Jul 01 Javascript
使用ajaxfileupload.js实现上传文件功能
Aug 13 Javascript
在javascript中使用com组件的简单实现方法
Aug 17 Javascript
MUI 解决动态列表页图片懒加载再次加载不成功的bug问题
Apr 13 Javascript
axios简单实现小程序延时loading指示
Jul 30 Javascript
webpack4 optimization使用总结
Nov 10 Javascript
如何在JavaScript中使用localStorage详情
Feb 04 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中加密解密函数与DES加密解密实例
2014/10/17 PHP
php导入大量数据到mysql性能优化技巧
2014/12/29 PHP
php编程实现简单的网页版计算器功能示例
2017/04/26 PHP
js 图片轮播(5张图片)
2008/12/30 Javascript
javascript EXCEL 操作类代码
2009/07/30 Javascript
js setattribute批量设置css样式
2009/11/26 Javascript
被jQuery折腾得半死,揭秘为何jQuery为何在IE/Firefox下均无法使用
2010/01/22 Javascript
JQuery+DIV自定义滚动条样式的具体实现
2013/06/25 Javascript
用javascript关闭本窗口不弹出询问框的方法
2014/09/12 Javascript
深入理解javascript作用域和闭包
2014/09/23 Javascript
jQuery+ajax+asp.net获取Json值的方法
2016/06/08 Javascript
bootstrapValidator表单验证插件学习
2016/12/30 Javascript
js实现消息滚动效果
2017/01/18 Javascript
Javascript DOM事件操作小结(监听鼠标点击、释放,悬停、离开等)
2017/01/20 Javascript
JavaScript之创意时钟项目(实例讲解)
2017/10/23 Javascript
Jquery的autocomplete插件用法及参数讲解
2019/03/12 jQuery
vue生命周期的探索
2019/04/03 Javascript
jQuery实现的记住帐号密码功能完整示例
2019/08/03 jQuery
使用Easyui实现查询条件的后端传递并自动刷新表格的两种方法
2019/09/09 Javascript
JQuery常用选择器功能与用法实例分析
2019/12/23 jQuery
PyCharm 常用快捷键和设置方法
2017/12/20 Python
css3加js做一个简单的3D行星运转效果实例代码
2017/01/18 HTML / CSS
CSS3移动端vw+rem不依赖JS实现响应式布局的方法
2019/01/23 HTML / CSS
Unix控制后台进程都有哪些进程
2016/09/22 面试题
超市国庆节促销方案
2014/02/20 职场文书
学习决心书范文
2014/03/11 职场文书
大学生职业生涯规划书
2014/03/14 职场文书
公司离职证明标准范本
2014/10/05 职场文书
护理专业自荐信范文
2015/03/06 职场文书
2015年客房服务员工作总结
2015/05/15 职场文书
教师远程研修感悟
2015/11/18 职场文书
2019年大学生职业生涯规划书
2019/03/25 职场文书
企业开发CSS命名BEM代码规范实践
2022/02/12 HTML / CSS
Tomcat执行startup.bat出现闪退的原因及解决办法
2022/04/20 Servers
Redis实现分布式锁的五种方法详解
2022/06/14 Redis
Python 第三方库 openpyxl 的安装过程
2022/12/24 Python