JavaScript: Distinguish between native and non-native member
Is there any way to detect whether a given function, say Array.prototype.for开发者_开发百科Each
, is a native function (e.g. the browser implements ECMAScript5) or a function added by a page's JavaScript script(s)?
You can try putting it to the console and seeing what comes up there.
I would say : alert(function);
If it pops as "native code" then it is native code...
Take advantage of the enumerable property of a native method.
function isNative(prop){
var op= this.prototype;
if(prop in op){
for(var p in op){
if(p=== prop){
return false;
}
}
return true
}
return null;
}
isNative.call(Array, 'map');
This uses a technique that seems to work in browsers I've tried (though I don't think it's specified by a standard):
function checkMethodType(m) {
if (!m) {
return("doesn't exist");
} else if (m.toString().search(/\[native code\]/) != -1) {
return("native");
} else {
return("non-native");
}
}
checkMethodType(Array.prototype.forEach); // native in modern browsers
checkMethodType(Array.prototype.myMethod); // non-native
jsFiddle here: http://jsfiddle.net/jfriend00/GJJqQ/.
This technique is non-standard and is not guaranteed to be reliable. In fact, you can fool it if you want to by putting the [native code] string in a non-native method. But, it might be useful anyway depending upon what you want it for. I'm not aware of any 100% reliable method.
For those suggesting the "native code" method:
function Foo() {}
Foo.prototype.toString = function() {
return 'function slice() {\n [native code]\n}';
}
var foo = new Foo();
alert(foo);
/* Shows:
** function Array() {
** [native code]
** }
*/
Some browsers will also include the phrase "native code" for host objects.
Als, according to ECMA-262 §4.3.6:
native object
object in an ECMAScript implementation whose semantics are fully defined by this specification rather than by the host environment.
NOTE Standard native objects are defined in this specification. Some native objects are built-in; others may be constructed during the course of execution of an ECMAScript program.
So if an Array.prototype.forEach method was added by user code, then it is a native object. Perhaps the OP really meant built–in method.
This isn't perfect but pretty much as close as you can get. I believe Opera(?some version?) doesn't properly support decompiling of Function
s, nor does Opera mobile. It You call what you want to do. It also avoids RobG's evil hackery.
function isNative(obj){
var toString = obj.toString;
delete obj.toString;
var ret = obj.toString().match(/\s*function\s+([a-z0-9]+)\s*\(\s*\)\s*{\s*\[native code\]/i)
obj.toString = toString;
return ret;
}
It also returns the functions name for example
isNative(window.Array)[1] = "Array"
精彩评论