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 相关文章推荐
Dom 学习总结以及实例的使用介绍
Apr 24 Javascript
零基础搭建Node.js、Express、Ejs、Mongodb服务器及应用开发入门
Dec 20 Javascript
JavaScript控制listbox列表框的项目上下移动的方法
Mar 18 Javascript
基于jquery实现放大镜效果
Aug 17 Javascript
js数组如何添加json数据及js数组与json的区别
Oct 27 Javascript
基于jQuery实现的双11天猫拆红包抽奖效果
Dec 01 Javascript
浅析jQuery 3.0中的Data
Jun 14 Javascript
微信小程序 定义全局数据、函数复用、模版等详细介绍
Oct 27 Javascript
使用 vue 实例更好的监听事件及vue实例的方法
Apr 22 Javascript
Vue $mount实战之实现消息弹窗组件
Apr 22 Javascript
聊聊Vue中provide/inject的应用详解
Nov 10 Javascript
用Golang运行JavaScript的实现示例
Nov 25 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中$_SERVER[PHP_SELF] 和 $_SERVER[SCRIPT_NAME]之间的区别
2009/09/05 PHP
PHP 压缩文件夹的类代码
2009/11/05 PHP
Yii操作数据库的3种方法
2014/03/11 PHP
简单实用的PHP防注入类实例
2014/12/05 PHP
PHP微信网页授权的配置文件操作分析
2019/05/29 PHP
JQuery toggle使用分析
2009/11/16 Javascript
70+漂亮且极具亲和力的导航菜单设计国外网站推荐
2011/09/20 Javascript
jQuery+CSS 实现随滚动条增减的汽水瓶中的液体效果
2011/09/26 Javascript
查看图片(前进后退)功能实现js代码
2013/04/24 Javascript
用示例说明filter()与find()的用法以及children()与find()的区别分析
2013/04/26 Javascript
jQuery输入城市查看地图使用介绍
2013/05/08 Javascript
Extjs中ComboBoxTree实现的下拉框树效果(自写)
2013/05/28 Javascript
js使用循环清空某个div中的input标签值
2014/09/29 Javascript
js手机号4位显示空格,银行卡每4位显示空格效果
2017/03/23 Javascript
详解如何在webpack中做预渲染降低首屏空白时间
2018/08/22 Javascript
js常用正则表达式集锦
2019/05/17 Javascript
基于Taro的微信小程序模板消息-获取formId功能模块封装实践
2019/07/15 Javascript
Vue之Mixins(混入)的使用方法
2019/09/24 Javascript
浅谈vue3中effect与computed的亲密关系
2019/10/10 Javascript
JS实现分页导航效果
2020/02/19 Javascript
[06:09]辉夜杯主赛事开幕式
2015/12/25 DOTA
Python验证企业工商注册码
2015/10/25 Python
python设置环境变量的作用和实例
2019/07/09 Python
Python argparse模块使用方法解析
2020/02/20 Python
python实现将字符串中的数字提取出来然后求和
2020/04/02 Python
关于keras.layers.Conv1D的kernel_size参数使用介绍
2020/05/22 Python
Python判断远程服务器上Excel文件是否被人打开的方法
2020/07/13 Python
CSS3中box-shadow的用法介绍
2015/07/15 HTML / CSS
TripAdvisor斯洛伐克:阅读评论、比较价格和酒店预订
2018/04/25 全球购物
《唯一的听众》教学反思
2014/02/20 职场文书
教师对学生的寄语
2014/04/03 职场文书
《真想变成大大的荷叶》教学反思
2014/04/14 职场文书
岗位明星事迹材料
2014/05/18 职场文书
水电维修专业推荐信
2014/09/06 职场文书
Golang标准库syscall详解(什么是系统调用)
2021/05/25 Golang
Golang 字符串的常见操作
2022/04/19 Golang