JavaScript中判断原生函数检查function是否是原生代码


Posted in Javascript onSeptember 09, 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 相关文章推荐
页面装载js及性能分析方法介绍
Mar 21 Javascript
加载列表时jquery获取ul中第一个li的属性
Nov 02 Javascript
javascript使用smipleChart实现简单图表
Jan 02 Javascript
Node.js 异步编程之 Callback介绍(一)
Mar 30 Javascript
jquery-tips悬浮提示插件分享
Jul 31 Javascript
Bootstrap+jfinal实现省市级联下拉菜单
May 30 Javascript
bootstrap laydate日期组件使用详解
Jan 04 Javascript
详解vue与后端数据交互(ajax):vue-resource
Mar 16 Javascript
10 种最常见的 Javascript 错误(频率最高)
Feb 08 Javascript
vue+vuex+axios实现登录、注册页权限拦截
Mar 09 Javascript
Vue中的字符串模板的使用
May 17 Javascript
微信小程序实现点击页面出现文字
Sep 21 Javascript
三种取消选中单选框radio的方法
Sep 09 #Javascript
使用JQuery库提供的扩展功能实现自定义方法
Sep 09 #Javascript
JQuery 给元素绑定click事件多次执行的解决方法
Sep 09 #Javascript
一个实用的图片切换支持点击切换和自动轮播
Sep 09 #Javascript
用JavaScript实现用一个DIV来包装文本元素节点
Sep 09 #Javascript
点击button获取text内容并改变样式的js实现
Sep 09 #Javascript
js 数组去重的四种实用方法
Sep 09 #Javascript
You might like
超神学院:鹤熙已踏入神圣领域,实力不比凯莎弱
2020/03/02 国漫
PHP 用数组降低程序的时间复杂度
2009/12/04 PHP
PHP开发框架kohana中处理ajax请求的例子
2014/07/14 PHP
php获取文章上一页与下一页的方法
2014/12/01 PHP
Yii列表定义与使用分页方法小结(3种方法)
2016/07/15 PHP
laravel学习笔记之模型事件的几种用法示例
2017/08/15 PHP
基于jquery的一个OutlookBar类,动态创建导航条
2010/11/19 Javascript
Jquery中的层次选择器与find()的区别示例介绍
2014/02/20 Javascript
javascript中的this详解
2014/12/08 Javascript
基于zepto.js实现仿手机QQ空间的大图查看组件ImageView.js详解
2015/03/05 Javascript
jQuery结合ajax实现动态加载文本内容
2015/05/19 Javascript
Jquery结合HTML5实现文件上传
2015/06/25 Javascript
JS读写CSS样式的方法汇总
2016/08/16 Javascript
浅析Angular2子模块以及异步加载
2017/04/24 Javascript
Angular表格神器ui-grid应用详解
2017/09/29 Javascript
微信小程序简单实现form表单获取输入数据功能示例
2017/11/30 Javascript
用p5.js制作烟花特效的示例代码
2018/03/21 Javascript
webpack-url-loader 解决项目中图片打包路径问题
2019/02/15 Javascript
[00:35]DOTA2上海特级锦标赛 VP战队宣传片
2016/03/04 DOTA
Python和Ruby中each循环引用变量问题(一个隐秘BUG?)
2014/06/04 Python
python 远程统计文件代码分享
2015/05/14 Python
通过Python爬虫代理IP快速增加博客阅读量
2016/12/14 Python
Python编程判断一个正整数是否为素数的方法
2017/04/14 Python
Django之无名分组和有名分组的实现
2019/04/16 Python
Python实现i人事自动打卡的示例代码
2020/01/09 Python
Python批量启动多线程代码实例
2020/02/18 Python
python装饰器代码深入讲解
2021/03/01 Python
全面解析CSS Media媒体查询使用操作(推荐)
2017/08/15 HTML / CSS
Myprotein蛋白粉美国官网:欧洲畅销运动营养品牌
2016/11/15 全球购物
一名老师的自我评价
2014/02/07 职场文书
党建工作经验交流材料
2014/05/25 职场文书
关于美容院的活动方案
2014/08/14 职场文书
商场圣诞节活动总结
2015/05/06 职场文书
关于军训的感想
2015/08/07 职场文书
如何写好开幕词?
2019/06/24 职场文书
Oracle查看表空间使用率以及爆满解决方案详解
2022/07/23 Oracle