Question Comment puis-je vérifier si une variable javascript est un type de fonction?


Supposons que j'ai une variable, qui est définie comme suit:

var a = function() {/* Statements */};

Je veux une fonction qui vérifie si le type de la variable est semblable à une fonction. c'est à dire. :

function foo(v) {if (v is function type?) {/* do something */}};
foo(a);

Comment puis-je vérifier si la variable 'a' est de type fonction de la manière définie ci-dessus?


659
2018-05-14 05:27


origine


Réponses:


Bien sûr, le moyen de souligner est plus efficace, mais la meilleure façon de vérifier, quand l'efficacité n'est pas un problème, est écrite sur la page de underscore liée par @Paul Rosania.

Inspiré par le trait de soulignement, la fonction isFunction finale est la suivante:

function isFunction(functionToCheck) {
 return functionToCheck && {}.toString.call(functionToCheck) === '[object Function]';
}

281
2017-09-09 02:24



if (typeof v === "function") {
    // do something
}

1267
2018-05-14 05:31



Underscore.js utilise un test plus élaboré mais très performant:

_.isFunction = function(obj) {
  return !!(obj && obj.constructor && obj.call && obj.apply);
};

Voir: http://jsperf.com/alternative-isfunction-implementations

EDIT: les tests mis à jour suggèrent que typeof pourrait être plus rapide, voir http://jsperf.com/alternative-isfunction-implementations/4


116
2018-05-14 05:33



Il y a plusieurs façons, donc je vais les résumer tous

  1. Le meilleur moyen est:
    
    function foo (v) {if (v instanceof Fonction) {/ * faire quelque chose * /}};
    
    
    Solution la plus performante (sans comparaison de chaînes de caractères) et élégante - l'opérateur instanceof a été pris en charge dans les navigateurs depuis très longtemps, donc ne vous inquiétez pas - cela fonctionnera dans IE 6.
  2. Le meilleur moyen est:
    
    function foo (v) {if (typeof v === "fonction") {/ * faire quelque chose * /}};
    
    
    inconvénient de typeof est-ce qu'il est susceptible d'échec silencieux, mauvais, donc si vous avez une faute de frappe (par exemple "finction") - dans ce cas le `if` retournera juste faux et vous ne saurez pas que vous avez une erreur jusqu'à plus tard dans votre code
  3. La meilleure façon suivante est:
    
    Fonction isFunction (functionToCheck) {
        var getType = {};
        return functionToCheck && getType.toString.call (functionToCheck) === '[objet Fonction]';
    }
    
    
    Cela n'a aucun avantage sur la solution # 1 ou # 2 mais est beaucoup moins lisible. Une version améliorée de ceci est
    
    fonction isFunction (x) {
        return Object.prototype.toString.call (x) == '[objet Fonction]';
    }
    
    
    mais encore beaucoup moins sémantique que la solution # 1

81
2017-10-31 22:50



jQuery  Référence

$.isFunction(functionName);

AngularJS  Référence

angular.isFunction(value);

Lodash  Référence

_.isFunction(value);

Souligner  Référence

_.isFunction(object); 

Node.js obsolète depuis la version 4.0.0 Référence

var util = require('util');
util.isFunction(object);

59
2018-01-27 17:16



@grandecomplex: Il y a beaucoup de verbosité dans votre solution. Ce serait beaucoup plus clair s'il était écrit comme ceci:

function isFunction(x) {
  return Object.prototype.toString.call(x) == '[object Function]';
}

53
2018-03-02 18:37



var foo = function(){};
if (typeof foo === "function") {
  alert("is function")
}


46
2018-01-28 05:56



Essayez instanceof: Il semble que toutes les fonctions héritent de la classe "Function":

// 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

20
2018-04-22 14:18



Un autre moyen simplement:

var fn = function () {}
if (fn.constructor === Function) {
  // true
} else {
  // false
}

10
2018-04-01 14:13



Si vous utilisez Lodash, vous pouvez le faire avec _.isFunction.

_.isFunction(function(){});
// => true

_.isFunction(/abc/);
// => false

_.isFunction(true);
// => false

_.isFunction(null);
// => false

Cette méthode renvoie true si la valeur est une fonction, sinon false.


5
2018-04-25 09:41



Pour ceux qui sont intéressés par le style fonctionnel, ou cherche une approche plus expressive à utiliser dans la programmation méta (comme la vérification de type), il pourrait être intéressant de voir Ramda bibliothèque pour accomplir une telle tâche.

Le code suivant ne contient que des fonctions pures et sans point:

const R = require('ramda');

const isPrototypeEquals = R.pipe(Object.getPrototypeOf, R.equals);

const equalsSyncFunction = isPrototypeEquals(() => {});

const isSyncFunction = R.pipe(Object.getPrototypeOf, equalsSyncFunction);

À partir de ES2017, async Les fonctions sont disponibles, nous pouvons donc les vérifier aussi:

const equalsAsyncFunction = isPrototypeEquals(async () => {});

const isAsyncFunction = R.pipe(Object.getPrototypeOf, equalsAsyncFunction);

Et puis combinez-les ensemble:

const isFunction = R.either(isSyncFunction, isAsyncFunction);

Bien sûr, la fonction devrait être protégée contre nullet undefined valeurs, afin de le rendre "sûr":

const safeIsFunction = R.unless(R.isNil, isFunction);

Et, extrait complet pour résumer:

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 ));

Cependant, notez que cette solution pourrait montrer moins de performance que les autres options disponibles en raison de l'utilisation intensive de fonctions d'ordre supérieur.


5
2017-12-23 22:44