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 相关文章推荐
JavaScript加密解密7种方法总结分析
Oct 07 Javascript
javascript prototype,executing,context,closure
Dec 24 Javascript
Jquery下的26个实用小技巧(jQuery tips, tricks & solutions)
Mar 01 Javascript
jQuery基于当前元素进行下一步的遍历
May 20 Javascript
JavaScript中常见获取元素的方法汇总
Mar 04 Javascript
node-webkit打包成exe文件被360误报木马的解决方法
Mar 11 Javascript
JS实现求数组起始项到终止项之和的方法【基于数组扩展函数】
Jun 13 Javascript
关于页面刷新vuex数据消失问题解决方案
Jul 03 Javascript
jquery手机触屏滑动拼音字母城市选择器的实例代码
Dec 11 jQuery
微信小程序实现弹出层效果
May 26 Javascript
使用 Element UI Table 的 slot-scope方法
Oct 10 Javascript
Vue+Java 通过websocket实现服务器与客户端双向通信操作
Sep 22 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
JavaScript 获取事件对象的注意点
2009/07/29 Javascript
jQuery EasyUI API 中文文档 - Tree树使用介绍
2011/11/19 Javascript
jQuery数组处理代码详解(含实例演示)
2012/02/03 Javascript
js操作输入框提示信息且响应鼠标事件
2014/03/25 Javascript
js图片处理示例代码
2014/05/12 Javascript
jquery的attr方法禁用表单元素禁用输入内容
2014/06/23 Javascript
js实现防止被iframe的方法
2015/07/03 Javascript
javascript设计简单的秒表计时器
2020/09/05 Javascript
基于jquery实现页面滚动到底自动加载数据的功能
2015/12/19 Javascript
javascript截图 jQuery插件imgAreaSelect使用详解
2016/05/04 Javascript
简单理解vue中el、template、replace元素
2016/10/27 Javascript
bootstrap导航、选项卡实现代码
2016/12/28 Javascript
浅谈Node.js轻量级Web框架Express4.x使用指南
2017/05/03 Javascript
解决vue中对象属性改变视图不更新的问题
2018/02/23 Javascript
node中modules.exports与exports导出的区别
2018/06/08 Javascript
Javascript读写cookie的实例源码
2019/03/16 Javascript
vue+element创建动态的form表单及动态生成表格的行和列
2019/05/20 Javascript
javascript关于“时间”的一次探索
2019/07/24 Javascript
NodeJs crypto加密制作token的实现代码
2019/11/15 NodeJs
Python中enumerate()函数编写更Pythonic的循环
2018/03/06 Python
django做form表单的数据验证过程详解
2019/07/26 Python
Python实现微信机器人的方法
2019/09/06 Python
AUC计算方法与Python实现代码
2020/02/28 Python
Django框架实现在线考试系统的示例代码
2020/11/30 Python
10种CSS3实现的loading动画,挑一个走吧?
2020/11/16 HTML / CSS
使用HTML5的表单验证的简单示例
2015/09/09 HTML / CSS
荷兰网上药店:Drogisterij.net
2019/09/03 全球购物
马来西亚在线健康商店:Medipal Malaysia
2020/04/13 全球购物
what is the difference between ext2 and ext3
2015/08/25 面试题
《悯农》教学反思
2014/04/28 职场文书
少先队活动总结
2014/08/29 职场文书
查摆问题整改措施
2014/10/24 职场文书
防溺水主题班会教案
2015/08/12 职场文书
《百分数的认识》教学反思
2016/02/19 职场文书
2016年读书月活动总结范文
2016/04/06 职场文书
Python3 多线程(连接池)操作MySQL插入数据
2021/06/09 Python