function isFuncNative(f) {
return !!f && (typeof f).toLowerCase() == 'function'
&& (f === Function.prototype
|| /^\s*function\s*(\b[a-z$_][a-z0-9$_]*\b)*\s*\((|([a-z$_][a-z0-9$_]*)(\s*,[a-z$_][a-z0-9$_]*)*)\)\s*{\s*\[native code\]\s*}\s*$/i.test(String(f)));
}
esto debería ser lo suficientemente bueno. esta función realiza las siguientes pruebas:
- null o undefined;
- el param es en realidad una función;
- el parámetro es en sí mismo Function.prototype (este es un caso especial, donde Function.prototype.toString da
function Empty(){}
)
- el cuerpo de la función es exactamente
function <valid_function_name> (<valid_param_list>) { [native code] }
la expresión regular es un poco complicado, pero lo que realmente funciona bastante decentemente rápido en cromo en mi portátil Lenovo 4 GB (core duo):
var n = (new Date).getTime();
for (var i = 0; i < 1000000; i++) {
i%2 ? isFuncNative(isFuncNative) :
isFuncNative(document.getElementById);
};
(new Date).getTime() - n;
3023ms. por lo que la función tarda alrededor de 3 microsegundos para ejecutarse una vez que todo está JIT.
Funciona en todos los navegadores. Anteriormente, utilicé Function.prototype.toString.call, esto bloquea IE, ya que en IE, los métodos de elemento DOM y los métodos de ventana NO son funciones, sino objetos, y no tienen el método toString. El constructor de cadenas resuelve el problema elegantemente.
Esto sólo funcionaría si toString no había sido anulado, no? – joekarl
@jAndy ¿Es esto infalible? Pensé que 'toString' no funciona en todos los navegadores modernos o algo así. – William
@joekit si se sobreescribe 'toString' usted debería poder hacer' Function.prototype.toString.call (obj) .indexOf ('[native code]'); 'También probablemente sería una mejor idea usar RegExp. Intente llamar a la función contra sí mismo, y se vería como ** nativo ** porque aparece en la cadena. – William