在我的开发工作中经常会遇到需要判断一个函数是否是JavaScript原生函数的情况,有时候这是一个很必要的工作,你需要知道这个函数是浏览器自身提供的,还是由第三方封装、伪装成原生函数。当然,最好的方法是考察执行这个函数的toString方法的返回值。
The JavaScript完成这个任务的方法非常简单:
function isNative(fn) { return (/\{\s*\[native code\]\s*\}/).test('' + fn); }toString方法会返回这个方法的字符串形式,然后用正则表达式判断里面包含的字符。
更强悍的方法Lodash的创始人John-David Dalton找到了一个更佳的方案:
;(function() { // Used to resolve the internal `[[Class]]` of values var toString = Object.prototype.toString; // Used to resolve the decompiled source of functions var fnToString = Function.prototype.toString; // Used to detect host constructors (Safari > 4; really typed array specific) var reHostCtor = /^\[object .+?Constructor\]$/; // Compile a regexp using a common native method as a template. // We chose `Object#toString` because there's a good chance it is not being mucked with. var reNative = RegExp('^' + // Coerce `Object#toString` to a string String(toString) // Escape any special regexp characters .replace(/[.*+?^${}()|[\]\/\\]/g, '\\$&') // Replace mentions of `toString` with `.*?` to keep the template generic. // Replace thing like `for ...` to support environments like Rhino which add extra info // such as method arity. .replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' ); function isNative(value) { var type = typeof value; return type == 'function' // Use `Function#toString` to bypass the value's own `toString` method // and avoid being faked out. ? reNative.test(fnToString.call(value)) // Fallback to a host object check because some environments will represent // things like typed arrays as DOM methods which may not conform to the // normal native pattern. : (value && type == 'object' && reHostCtor.test(toString.call(value))) || false; } // export however you want module.exports = isNative; }());现在你也看到了,很复杂,但更强大。当然,这不是为了做安全防护,它只是给你提供是否是原生函数的相关信息。
分享这篇文章:
分享
分享
分享
分享
分享
3
2014年9月7日 下午5:12
只学习了js的基础.先收藏了
2014年9月30日 下午12:53
瞎说
2014年10月27日 下午12:43
如果真正要伪装原生函数,文中的办法是检测不出来的。
例如下面这个函数:
var fakeNative = (function() { console.log(“this is not native”); }).bind(null)
实际上你用toString只会看到
function () { [native code] }
检测也是检测不出来的。
当然一般的库不会刻意伪装成原生函数,但是足以证明文中方法并不可靠。
其实一般而言也不需要检测一个函数是否原生,即使是Javascript,也依然可以利用面向接口编程的思考方式,这样的话,完全可以假定原生方法存在,然后提供优雅降级。
我认为这才是正确的Javascript用法。
发表评论
中文版濒危动物CSS碎片拼图
这里我们用纯CSS技术表现出30种动物的碎片拼图形象,这30动物,非常的可爱,但不幸的是,它们都是濒临灭绝的动物,它们的生存情况正面临着危机。
HTML5小游戏:蓝色拼图
这是一个用HTML5制作的智力游戏,有相当的难度。每个方块一面橙色,一面蓝色。点击一个方块,这个方块的颜色会翻转,并且,与它邻接的方块的颜色也会翻转。使拼板全部变成蓝色, 你就算过关了。
CSS颜色混合模式
虽然并不是Adobe的Photoshop发明了混合模式,但它的实现效果是最真实的。但现在,你不需要使用Photoshop来运用混合模式美化你的图片,因为CSS3里提供里动态的实现这种效果的方法。
你能相信吗?这些都是由一个DIV元素实现的动画,纯CSS3技术