JavaScript检测原生函数的两种实现方式
作者:小括号时间:2026-10-28 13:32:25浏览:387
本文介绍在JavaScript中检测函数是否为浏览器原生代码的两种方法。第一种通过判断函数toString返回值是否包含[native code]字符串实现;第二种基于Object.prototype.toString和Function.prototype.toString构建更完善的检测逻辑,以区分宿主对象构造器与真正的原生方法。
检测原生函数的需求与原理
在功能测试场景中,经常需要确认某个函数是浏览器内置支持的原生代码,还是由第三方类库模拟实现的。最简单直接的检测手段是查看该函数的toString方法所返回的字符串内容。
JavaScript代码
判断函数是否是原生方法其实相当简单:
基础实现:基于toString的正则匹配
// 判断是否原生函数
function isNative(fn) {
// 示例:
// alert.toString()
// "function alert() { [native code] }"
// '' + fn 利用了js的隐式类型转换.
return (/\{\s*\[native code\]\s*\}/).test('' + fn);
}
其实现原理是将函数转换为字符串表示形式,然后使用正则表达式进行匹配判断。
升级版,Update!
进阶实现:综合Object与Function原型检测
;(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
作者最新文章
JS语法错误会阻止加载吗?区分SyntaxError与资源加载失败
2026-11-05 16:08:46
JavaScript常见SyntaxError语法错误排查与修复方法
2026-11-05 13:58:44
JS中slice、substring和substr截取字符串的区别
2026-11-05 13:43:47
JS 转 TS 手动迁移最佳实践:从配置 tsconfig 到消除 any 类型
2026-11-05 11:53:32
为什么JS数组push后得到的是数字而不是数组?
2026-11-05 09:59:18
