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 相关文章推荐
javascript 在网页中的运用(asp.net)
Nov 23 Javascript
Js 随机数产生6位数字
May 13 Javascript
javascript获取web应用根目录的方法
Feb 12 Javascript
jquery获取radio值(单选组radio)
Oct 16 Javascript
JavaScript中实现无缝滚动、分享到侧边栏实例代码
Apr 06 Javascript
javascript表单处理具体实现代码(表单、链接、按钮)
May 07 Javascript
AngularJS 单元测试(二)详解
Sep 21 Javascript
如何在Vue中使用CleaveJS格式化你的输入内容
Dec 14 Javascript
使用form-create动态生成vue自定义组件和嵌套表单组件
Jan 18 Javascript
学习LayUI时自研的表单参数校验框架案例分析
Jul 29 Javascript
微信小程序实现左侧滑动导航栏
Apr 08 Javascript
js面向对象之实现淘宝放大镜
Jan 15 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基于GD库画五星红旗的方法
2015/02/24 PHP
php打印一个边长为N的实心和空心菱型的方法
2015/03/02 PHP
php实现在线通讯录功能(附源码)
2016/05/13 PHP
javascript时间函数基础介绍
2013/03/28 Javascript
JS图片切换的具体方法(带缩略图版)
2013/11/12 Javascript
页面加载完毕后滚动条自动滚动一定位置
2014/02/20 Javascript
jQuery如何取id有.的值一般的方法是取不到的
2014/04/18 Javascript
编写高质量JavaScript代码的基本要点
2016/03/02 Javascript
jQuery中show与hide方法用法示例
2016/09/16 Javascript
jquery获取table指定行和列的数据方法(当前选中行、列)
2016/11/07 Javascript
原生js实现手风琴功能(支持横纵向调用)
2017/01/13 Javascript
微信小程序利用co处理异步流程的方法教程
2017/05/20 Javascript
JavaScript实现的仿新浪微博原生态输入字数即时检查功能【兼容IE6】
2017/09/26 Javascript
JavaScript 保护变量不被随意修改的实现代码
2017/09/27 Javascript
vue中实现移动端的scroll滚动方法
2018/03/03 Javascript
关于js的三种使用方式(行内js、内部js、外部js)的程序代码
2018/05/05 Javascript
vue微信分享出来的链接点开是首页问题的解决方法
2018/11/28 Javascript
JavaScript ES6中的简写语法总结与使用技巧
2018/12/30 Javascript
vue无限轮播插件代码实例
2019/05/10 Javascript
node.js域名解析实现方法详解
2019/11/05 Javascript
jQuery实现全选按钮
2021/01/01 jQuery
[04:40]2016国际邀请赛中国区预选赛全程TOP10镜头集锦
2016/07/01 DOTA
Python入门篇之列表和元组
2014/10/17 Python
django 单表操作实例详解
2019/07/30 Python
python中的TCP(传输控制协议)用法实例分析
2019/11/15 Python
tensorflow中tf.reduce_mean函数的使用
2020/04/19 Python
什么是python的列表推导式
2020/05/26 Python
人口与计划生育目标管理责任书
2014/07/29 职场文书
安全例会汇报材料
2014/08/23 职场文书
房地产端午节活动方案
2014/08/24 职场文书
出国签证在职证明
2014/09/20 职场文书
学校领导班子对照检查材料
2014/09/24 职场文书
乡镇遵守党的政治纪律情况对照检查材料
2014/09/26 职场文书
诗词赏析-(浣溪沙)
2019/08/13 职场文书
常用的MongoDB查询语句的示例代码
2021/07/25 MongoDB
Ruby GDBM操作简介及数据存储原理
2022/04/19 Ruby