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 相关文章推荐
学习YUI.Ext 第七天--关于View&JSONView
Mar 10 Javascript
jQuery Dialog 弹出层对话框插件
Aug 09 Javascript
js与jQuery实现checkbox复选框全选/全不选的方法
Jan 05 Javascript
原生JS查找元素的方法(推荐)
Nov 22 Javascript
JavaScript实现Fly Bird小游戏
Dec 15 Javascript
localStorage的黑科技-js和css缓存机制
Feb 06 Javascript
10个最优秀的Node.js MVC框架
Aug 24 Javascript
解决js ajax同步请求造成浏览器假死的问题
Jan 18 Javascript
解决vue的 v-for 循环中图片加载路径问题
Sep 03 Javascript
js计算最大公约数和最小公倍数代码实例
Sep 11 Javascript
使用vue实现通过变量动态拼接url
Jul 22 Javascript
vue动态绑定style样式
Apr 20 Vue.js
使用时间戳解决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
咖啡冲泡指南 咖啡有哪些制作方式 单品咖啡 意式咖啡
2021/03/06 冲泡冲煮
需要发散思维学习PHP
2009/06/29 PHP
php 输出双引号"与单引号'的方法
2010/05/09 PHP
PHPCrawl爬虫库实现抓取酷狗歌单的方法示例
2017/12/21 PHP
laravel利用中间件防止未登录用户直接访问后台的方法
2019/09/30 PHP
js程序中美元符号$是什么
2008/06/05 Javascript
IE innerHTML,outerHTML所引起的问题
2009/06/04 Javascript
jQuery简单实现两级下拉菜单效果代码
2015/09/15 Javascript
jQuery实现带玻璃流光质感的手风琴特效
2015/11/20 Javascript
BootStrap实现手机端轮播图左右滑动事件
2016/10/13 Javascript
Node使用Sequlize连接Mysql报错:Access denied for user ‘xxx’@‘localhost’
2018/01/03 Javascript
vue-router的hooks用法详解
2020/06/08 Javascript
[48:30]LGD vs infamous Supermajor小组赛D组 BO3 第一场 6.3
2018/06/04 DOTA
[03:07]完美世界DOTA2联赛PWL DAY10 决赛集锦
2020/11/11 DOTA
基于Python实现定时自动给微信好友发送天气预报
2018/10/25 Python
用Python实现BP神经网络(附代码)
2019/07/10 Python
python 实现兔子生兔子示例
2019/11/21 Python
Anaconda配置pytorch-gpu虚拟环境的图文教程
2020/04/16 Python
python实现斗地主分牌洗牌
2020/06/22 Python
Django-imagekit的使用详解
2020/07/06 Python
python代码实现图书管理系统
2020/11/30 Python
Python中对象的比较操作==和is区别详析
2021/02/12 Python
法国综合购物网站:RueDuCommerce
2016/09/12 全球购物
材料成型专业个人求职信范文
2013/09/25 职场文书
艺术系应届生的自我评价
2013/10/19 职场文书
招商业务员岗位职责
2013/12/16 职场文书
敬老院院长事迹材料
2014/05/21 职场文书
学雷锋志愿者活动方案
2014/08/21 职场文书
教师民族团结演讲稿
2014/08/27 职场文书
财务个人年度总结范文
2015/02/26 职场文书
卫生院艾滋病宣传活动总结
2015/05/09 职场文书
《作风建设永远在路上》心得体会
2016/01/21 职场文书
改进工作作风心得体会
2016/01/23 职场文书
《只有一个地球》教学反思
2016/02/16 职场文书
七年级写作指导之游记作文
2019/10/07 职场文书
golang判断key是否在map中的代码
2021/04/24 Golang