Cómo determinar que una función de JavaScript es nativa(sin probar ''[código nativo]'')
node.js function (2)
Me gustaría saber si hay una manera de diferenciar una función de script de JavaScript ( function(){}
) de una función nativa de JavaScript (como Math.cos
).
Ya conozco el func.toString().indexOf(''[native code]'') != -1
pero me preguntaba si existe otra forma de detectarlo.
contexto:
Necesito crear un Proxy ES6 de reenvío sin operación que pueda manejar funciones nativas en un objeto, pero falla con TypeError: Illegal invocation
(consulte Error de invocación ilegal al usar Proxy ES6 y node.js ).
Para solucionar esto, .bind()
todas mis funciones en el controlador de get
de mi Proxy, pero si pudiera detectar la función nativa de manera efectiva, solo necesitaré .bind()
estas funciones nativas.
más detalles: https://github.com/FranckFreiburger/module-invalidate/blob/master/index.js#L106
Nota:
(function() {}).toString() -> "function () {}"
(function() {}).prototype -> {}
(require(''os'').cpus).toString() -> "function getCPUs() { [native code] }"
(require(''os'').cpus).prototype -> getCPUs {}
(Math.cos).toString() -> "function cos() { [native code] }"
(Math.cos).prototype -> undefined
(Promise.resolve().then).toString() -> "function then() { [native code] }"
(Promise.resolve().then).prototype -> undefined
editar:
Por el momento, la mejor solución es probar !(''prototype'' in fun)
pero no funcionará con require(''os'').cpus
...
Mi resumen sobre este tema: no lo use, no funciona. Ciertamente no puede detectar si una función es nativa, porque la Function#bind()
también crea funciones "nativas".
function isSupposedlyNative(fn){
return (//{/s*/[native code/]/s*/}/).test(fn);
}
function foo(){ }
var whatever = {};
console.log("Math.cos():", isSupposedlyNative( Math.cos ));
console.log("foo():", isSupposedlyNative( foo ));
console.log("foo.bind():", isSupposedlyNative( foo.bind(whatever) ));
Y dado que la Versión de John-David Dalton, a la que Tareq se vinculó en este comentario, hace básicamente lo mismo que el código tampoco funciona. Lo he comprobado.
Y el enfoque de Nina funciona en un principio similar, porque nuevamente es la parte [native code]
en el cuerpo de la función la que produce el error al intentar analizarlo en una nueva función.
La única forma segura de determinar si la función con la que está trabajando es la función nativa, es mantener una referencia a la función nativa y comparar su función con esa referencia, pero supongo que esta no es una opción para su caso de uso.
Podría try
usar un constructor de Function
con el valor toString
de la función. Si no se produce un error, se obtiene una función personalizada, de lo contrario tiene una función nativa.
function isNativeFn(fn) {
try {
void new Function(fn.toString());
} catch (e) {
return true;
}
return false;
}
function customFn() { var foo; }
console.log(isNativeFn(Math.cos)); // true
console.log(isNativeFn(customFn)); // false
console.log(isNativeFn(customFn.bind({}))); // true, because bind