una - typeof array javascript
¿Cómo puedo verificar si una variable de javascript es un tipo de función? (17)
Supongamos que tengo alguna variable, que se define de la siguiente manera:
var a = function() {/* Statements */};
Quiero una función que verifique si el tipo de la variable es similar a la función. es decir:
function foo(v) {if (v is function type?) {/* do something */}};
foo(a);
¿Cómo puedo verificar si la variable ''a'' es de tipo función en la forma definida anteriormente?
@grandecomplex: hay una gran cantidad de verbosidad en su solución. Sería mucho más claro si se escribe así:
function isFunction(x) {
return Object.prototype.toString.call(x) == ''[object Function]'';
}
Creo que solo puede definir una marca en el prototipo de función y verificar si la instancia que desea probar heredó eso
definir una bandera:
Function.prototype.isFunction = true;
y luego verifica si existe
var foo = function(){};
foo.isFunction; // will return true
La desventaja es que otro prototipo puede definir la misma bandera y luego no tiene ningún valor, pero si tiene control total sobre los módulos incluidos, es la forma más fácil.
Desde el nodo v0.11 puede usar la función util estándar:
var util = require(''util'');
util.isFunction(''foo'');
Encontré que al probar las funciones nativas del navegador en IE8, el uso de toString
, instanceof
y typeof
no funcionaba. Aquí hay un método que funciona bien en IE8 (que yo sepa):
function isFn(f){
return !!(f && f.call && f.apply);
}
//Returns true in IE7/8
isFn(document.getElementById);
Alternativamente, puede verificar las funciones nativas usando:
"getElementById" in document
Sin embargo, he leído en alguna parte que esto no siempre funcionará en IE7 y más adelante.
Hay varias formas, así que las resumiré todas.
- La mejor manera es:
function foo(v) {if (v instanceof Function) {/* do something */} }; La solución más elegante (sin comparación de cadenas) y elegante: la instancia del operador ha sido admitida en los navegadores durante mucho tiempo, así que no se preocupe, funcionará en IE 6.
- La siguiente mejor manera es:
function foo(v) {if (typeof v === "function") {/* do something */} }; La desventaja de
typeof
es que es susceptible a fallas silenciosas, malo, por lo que si tiene un error tipográfico (por ejemplo, "finction"), en este caso, el ''if'' devolverá false y no sabrá que tiene un error hasta más adelante en tu código - La siguiente mejor manera es:
function isFunction(functionToCheck) { var getType = {}; return functionToCheck && getType.toString.call(functionToCheck) === ''[object Function]''; } Esto no tiene ninguna ventaja sobre la solución # 1 o # 2, pero es mucho menos legible. Una versión mejorada de esto es
function isFunction(x) { return Object.prototype.toString.call(x) == ''[object Function]''; } pero todavía mucho menos semántico que la solución # 1
Intente instanceof: parece que todas las funciones heredan de la clase "Función":
// Test data
var f1 = function () { alert("test"); }
var o1 = { Name: "Object_1" };
F_est = function () { };
var o2 = new F_est();
// Results
alert(f1 instanceof Function); // true
alert(o1 instanceof Function); // false
alert(o2 instanceof Function); // false
La forma de subrayar con seguridad es más eficiente, pero la mejor manera de verificar, cuando la eficiencia no es un problema, está escrita en la página de subrayado vinculada a @Paul Rosania.
Inspirada en el guión bajo, la función isFunction final es la siguiente:
function isFunction(functionToCheck) {
return functionToCheck && {}.toString.call(functionToCheck) === ''[object Function]'';
}
La solución que han mostrado algunas respuestas anteriores es usar typeof. el siguiente es un fragmento de código en NodeJs,
function startx() {
console.log("startx function called.");
}
var fct= {};
fct["/startx"] = startx;
if (typeof fct[/startx] === ''function'') { //check if function then execute it
fct[/startx]();
}
Lo siguiente también parece funcionar para mí (probado desde node.js
):
var isFunction = function(o) {
return Function.prototype.isPrototypeOf(o);
};
console.log(isFunction(function(){})); // true
console.log(isFunction({})); // false
Otra forma sencilla:
var fn = function () {}
if (fn.constructor === Function) {
// true
} else {
// false
}
Para aquellos que estén interesados en el estilo funcional, o busquen un enfoque más expresivo para utilizar en la meta programación (como la comprobación de tipos), podría ser interesante ver la biblioteca Ramda para realizar dicha tarea.
El siguiente código contiene solo funciones puras y sin punto:
const R = require(''ramda'');
const isPrototypeEquals = R.pipe(Object.getPrototypeOf, R.equals);
const equalsSyncFunction = isPrototypeEquals(() => {});
const isSyncFunction = R.pipe(Object.getPrototypeOf, equalsSyncFunction);
A partir de ES2017, las funciones async
están disponibles, por lo que también podemos verificarlas:
const equalsAsyncFunction = isPrototypeEquals(async () => {});
const isAsyncFunction = R.pipe(Object.getPrototypeOf, equalsAsyncFunction);
Y luego combinarlos juntos:
const isFunction = R.either(isSyncFunction, isAsyncFunction);
Por supuesto, la función debe estar protegida contra valores null
e undefined
, para que sea "segura":
const safeIsFunction = R.unless(R.isNil, isFunction);
Y, un fragmento completo para resumir:
const R = require(''ramda'');
const isPrototypeEquals = R.pipe(Object.getPrototypeOf, R.equals);
const equalsSyncFunction = isPrototypeEquals(() => {});
const equalsAsyncFunction = isPrototypeEquals(async () => {});
const isSyncFunction = R.pipe(Object.getPrototypeOf, equalsSyncFunction);
const isAsyncFunction = R.pipe(Object.getPrototypeOf, equalsAsyncFunction);
const isFunction = R.either(isSyncFunction, isAsyncFunction);
const safeIsFunction = R.unless(R.isNil, isFunction);
// ---
console.log(safeIsFunction( function () {} ));
console.log(safeIsFunction( () => {} ));
console.log(safeIsFunction( (async () => {}) ));
console.log(safeIsFunction( new class {} ));
console.log(safeIsFunction( {} ));
console.log(safeIsFunction( [] ));
console.log(safeIsFunction( ''a'' ));
console.log(safeIsFunction( 1 ));
console.log(safeIsFunction( null ));
console.log(safeIsFunction( undefined ));
Sin embargo, tenga en cuenta que esta solución podría mostrar menos rendimiento que otras opciones disponibles debido al uso extensivo de las funciones de orden superior.
Si usas Lodash puedes hacerlo con _.isFunction .
_.isFunction(function(){});
// => true
_.isFunction(/abc/);
// => false
_.isFunction(true);
// => false
_.isFunction(null);
// => false
Este método devuelve true
si el valor es una función, sino false
.
Reference jQuery (en desuso desde la versión 3.3)
$.isFunction(functionName);
Reference AngularJS
angular.isFunction(value);
Reference Lodash
_.isFunction(value);
Reference subrayado
_.isFunction(object);
Node.js en desuso desde v4.0.0 Reference
var util = require(''util'');
util.isFunction(object);
Underscore.js utiliza una prueba más elaborada pero de alto rendimiento:
_.isFunction = function(obj) {
return !!(obj && obj.constructor && obj.call && obj.apply);
};
Consulte: http://jsperf.com/alternative-isfunction-implementations
EDITAR: las pruebas actualizadas sugieren que typeof podría ser más rápido, consulte http://jsperf.com/alternative-isfunction-implementations/4
typeOf
usar el operador typeOf
en js.
var a=function(){
alert("fun a");
}
alert(typeof a);// alerts "function"
var foo = function(){};
if (typeof foo === "function") {
alert("is function")
}
if (typeof v === "function") {
// do something
}