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 toggle()设置CSS样式
Nov 05 Javascript
validator验证控件使用代码
Nov 23 Javascript
JS代码同步文本框内容的实例方法
Jul 12 Javascript
window.navigate 与 window.location.href 的使用区别介绍
Sep 21 Javascript
js截取小数点后几位的写法
Nov 14 Javascript
javascript与Python快速排序实例对比
Aug 10 Javascript
EasyUI在Panel上动态添加LinkButton按钮
Aug 11 Javascript
Angularjs添加排序查询功能的实例代码
Oct 24 Javascript
jQuery实现动态添加节点与遍历节点功能示例
Nov 09 jQuery
简单了解TypeScript中如何继承 Error 类
Jun 21 Javascript
vue实现select下拉显示隐藏功能
Sep 30 Javascript
在实例中重学JavaScript事件循环
Dec 03 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
杏林同学录(九)
2006/10/09 PHP
php网站来路获取代码(针对搜索引擎)
2010/06/08 PHP
php数组中删除元素之重新索引的方法
2014/09/16 PHP
ThinkPHP中Common/common.php文件常用函数功能分析
2016/05/20 PHP
PHP实现多关键字加亮功能
2016/10/21 PHP
prototype 1.5 & scriptaculous 1.6.1 学习笔记
2006/09/07 Javascript
IE6中使用position导致页面变形的解决方案(js代码)
2011/01/09 Javascript
JS上传前预览图片实例
2013/03/25 Javascript
jquery实现鼠标滑过显示提示框的方法
2015/02/05 Javascript
javascript实现下拉提示选择框
2015/12/29 Javascript
AngularJS ng-mousedown 指令
2016/08/02 Javascript
Bootstrap源码学习笔记之bootstrap进度条
2016/12/24 Javascript
bootstrapValidator bootstrap-select验证不可用的解决办法
2017/01/11 Javascript
js防刷新的倒计时代码 js倒计时代码
2017/09/06 Javascript
layer插件select选中默认值的方法
2018/08/14 Javascript
js实现的订阅发布者模式简单示例
2020/03/14 Javascript
vue中v-for循环选中点击的元素并对该元素添加样式操作
2020/07/17 Javascript
你不知道的SpringBoot与Vue部署解决方案
2020/11/09 Javascript
如何在现代JavaScript中编写异步任务
2021/01/31 Javascript
[01:03:36]Ti4 循环赛第三日DK vs Titan
2014/07/12 DOTA
python中使用sys模板和logging模块获取行号和函数名的方法
2014/04/15 Python
python实现得到一个给定类的虚函数
2014/09/28 Python
python打开网页和暂停实例
2014/09/30 Python
Python中使用装饰器和元编程实现结构体类实例
2015/01/28 Python
CentOS中升级Python版本的方法详解
2017/07/10 Python
Django自带日志 settings.py文件配置方法
2019/08/30 Python
基于html5 canvas实现漫天飞雪效果实例
2014/09/10 HTML / CSS
WWE美国职业摔角官方商店:WWE Shop
2018/11/15 全球购物
请解释在new与override的区别
2012/10/29 面试题
市场部经理岗位职责
2015/02/02 职场文书
2015年公民道德宣传日活动总结
2015/03/23 职场文书
2015年司法所工作总结
2015/04/27 职场文书
幼儿园小班教育随笔
2015/08/14 职场文书
小学班主任工作经验交流材料
2015/11/02 职场文书
pygame面向对象的飞行小鸟实现(Flappy bird)
2021/04/01 Python
漫画《尖帽子的魔法工坊》宣布动画化
2022/04/06 日漫