Comment vérifier si la fonction existe en JavaScript?

534

Mon code est

function getID( swfID ){
     if(navigator.appName.indexOf("Microsoft") != -1){
          me = window[swfID];
     }else{
          me = document[swfID];
     }
}

function js_to_as( str ){
     me.onChange(str);
}

Cependant, parfois mon onChangene se charge pas. Erreurs Firebug avec

me.onChange n'est pas une fonction

Je veux me dégrader gracieusement car ce n'est pas la caractéristique la plus importante de mon programme. typeofdonne la même erreur.

Avez-vous des suggestions sur la façon de vous assurer qu'il existe et ensuite de l'exécuter uniquement onChange?

(Aucune des méthodes ci-dessous, sauf essayez d'attraper un travail)

Alec Smart
la source
1
@SteveChambers Je l'ai fait. Merci de me le rappeler.
Alec Smart
attraper l'exception. vérifier ma réponse
Matteus Barbosa

Réponses:

1227

Essayez quelque chose comme ceci:

if (typeof me.onChange !== "undefined") { 
    // safe to use the function
}

ou mieux encore (selon le commentaire de UpTheCreek)

if (typeof me.onChange === "function") { 
    // safe to use the function
}
Andrew Hare
la source
249
=== 'function' serait mieux que! = 'undefined'
UpTheCreek
3
@James, car cette instruction lève en fait une undefinedexception dans le JavaScript. Je l'ai essayé.
Mike Perrenoud
8
@UpTheCreek, ce serait un peu dangereux comme solution générale car les anciennes versions d'IE traitent certaines fonctions comme des objets, par exemple typeof window.alert === 'object'.
Noyo
1
Pourquoi ne pas simplement utiliser if (me.onChange) { // do something }?
BornToCode
3
@BornToCode, car il me.onChangepourrait alors s'agir de n'importe quoi true, pas nécessairement une fonction (par exemple, ce pourrait être un booléen, une chaîne, etc.). Par exemple, voir jsfiddle.net/j5KAF/1
Ohad Schneider
108

J'ai eu ce problème.

if (obj && typeof obj === 'function') { ... }

continuait à lancer une erreur de référence si obj n'était pas défini.

Au final, j'ai fait ce qui suit:

if (typeof obj !== 'undefined' && typeof obj === 'function') { ... }

Un collègue m'a fait remarquer que vérifier si c'est !== 'undefined'et puis === 'function'c'est redondant bien sûr.

Plus simple:

if (typeof obj === 'function') { ... }

Beaucoup plus propre et fonctionne très bien.

Misha Nasledov
la source
1
Quelqu'un sait pourquoi le premier extrait de code est lancé ReferenceError? Cela me semble illogique.
saidfagan
@saidfagan Voir la définition de ReferenceError developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Misha Nasledov
cela fonctionne pour moi
NewBie1234
1
Tout motif pour lequel typeof obj == 'fonction' serait insuffisant? ;-) Rappel: l'opérateur de test d'égalité stricte n'a de sens que lorsque l'opérande statique est vide ou nul ou 0 ou soumis à un amalgame cast comme celui-ci.
Fabien Haddadi
16

Si vous utilisez eval pour convertir une chaîne en fonction et que vous souhaitez vérifier si cette méthode évaluée existe, vous voudrez utiliser typeof et votre chaîne de fonction dans un eval :

var functionString = "nonexsitantFunction"
eval("typeof " + functionString) // returns "undefined" or "function"

N'inversez pas cela et essayez un typeof sur eval . Si vous faites une ReferenceError sera levée:

var functionString = "nonexsitantFunction"
typeof(eval(functionString)) // returns ReferenceError: [function] is not defined
dhulihan
la source
21
eval == evil;)
Yeti
1
Cela peut être mauvais, mais cela est très utile lorsque le nom de la fonction est dans une variable.
Luke Cousins
8
Vous pouvez le faire sans eval. Exemple:var a = 'alert'; window[a]('it works');
zennin
15

Que diriez-vous:

if('functionName' in Obj){
    //code
}

par exemple

var color1 = new String("green");
"length" in color1 // returns true
"indexOf" in color1 // returns true
"blablabla" in color1 // returns false

ou comme pour votre cas:

if('onChange' in me){
    //code
}

Voir les documents MDN .

Nasser Al-Wohaibi
la source
mais cette solution ne fonctionne pas à chaque fois :( par exemple si je veux le savoir, il y a lastIndexOf()dans la chaîne (nous savons, c'est-à-dire, mais théoriquement) typeof String().lastIndexOf === "function"c'est vrai, mais 'lastIndexOf' in Stringc'est faux.
iiic
10

Essayez typeof- Cherchez 'undefined'à dire qu'elle n'existe pas, 'function'pour une fonction. JSFiddle pour ce code

function thisishere() {
    return false;
}
alert("thisishere() is a " + typeof thisishere);
alert("thisisnthere() is " + typeof thisisnthere);

Ou comme si:

if (typeof thisishere === 'function') {
    // function exists
}

Ou avec une valeur de retour, sur une seule ligne:

var exists = (typeof thisishere === 'function') ? "Value if true" : "Value if false";
var exists = (typeof thisishere === 'function') // Returns true or false
Mat Carlson
la source
9

N'a pas vu cela suggéré: me.onChange && me.onChange (str);

Fondamentalement, si me.onChange n'est pas défini (ce qu'il sera s'il n'a pas été lancé), il n'exécutera pas la dernière partie. Si me.onChange est une fonction, elle exécutera me.onChange (str).

Vous pouvez même aller plus loin et faire:

me && me.onChange && me.onChange(str);

au cas où je serais asynchrone aussi.

Samir Alajmovic
la source
5
//Simple function that will tell if the function is defined or not
function is_function(func) {
    return typeof window[func] !== 'undefined' && $.isFunction(window[func]);
}

//usage

if (is_function("myFunction") {
        alert("myFunction defined");
    } else {
        alert("myFunction not defined");
    }
Muhammad Tahir
la source
votre solution n'est pas claire, car elle contient jQUery, ce qui est étrange en ce moment je pense, donc elle génère des erreurs lors de tests simples.
T.Todua
@tazotodua c'est une fonction qui s'explique d'elle-même. si vous souhaitez utiliser sans jquery. il suffit de retirer la partie &&. c'est une condition supplémentaire pour vérifier et éviter les erreurs.
Muhammad Tahir
Est-ce que la condition sur le côté gauche de la &&prise en charge de quelque chose que le jQuery isFunctionsur le côté droit du &&ne fait pas?
SantiBailors
5

Pour moi, le moyen le plus simple:

function func_exists(fname)
{
  return (typeof window[fname] === 'function');
}
Tu4n3r
la source
c'est la bonne réponse, car c'est une chaîne littérale .. Je dirais mieux comme ça if ((typeof window["function_name"] !== 'undefined') && ((typeof window["function_name"] === 'function'))) { return true; } else { return false; }mais c'est un ajustement mineur
Mr Heelis
4

Je vais aller plus loin pour m'assurer que la propriété est bien une fonction

function js_to_as( str ){
     if (me && me.onChange && typeof me.onChange === 'function') {
         me.onChange(str);
     }
}
Alex
la source
3
function js_to_as( str ){
     if (me && me.onChange)
         me.onChange(str);
}
MiffTheFox
la source
3

J'aime utiliser cette méthode:

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

Usage:

if ( isFunction(me.onChange) ) {
    me.onChange(str); // call the function with params
}
David Douglas
la source
3

La bibliothèque Underscore.js le définit dans la méthode isFunction comme ceci (ce que les commentaires suggèrent peut répondre à certains bogues du navigateur)

typeof obj == 'function' || false

http://underscorejs.org/docs/underscore.html#section-143

PandaWood
la source
3
function function_exists(function_name)
{
    return eval('typeof ' + function_name) === 'function';
}
alert(function_exists('test'));
alert(function_exists('function_exists'));

OU

function function_exists(func_name) {
  //  discuss at: http://phpjs.org/functions/function_exists/
  // original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  // improved by: Steve Clay
  // improved by: Legaev Andrey
  // improved by: Brett Zamir (http://brett-zamir.me)
  //   example 1: function_exists('isFinite');
  //   returns 1: true

  if (typeof func_name === 'string') {
    func_name = this.window[func_name];
  }
  return typeof func_name === 'function';
}
Mohammad Lotfi
la source
1
S'il vous plaît, quelques explications.
Gufran Hasan
Dans deux cas, appelez simplement function_exists avec le nom du paramètre de fonction pour vérifier l'existence, renvoie bool.
Mohammad Lotfi
3

Mettez un double point d'exclamation, c'est-à-dire !! avant le nom de la fonction que vous souhaitez vérifier. S'il existe, il retournera vrai.

function abc(){
}
!!window.abc; // return true
!!window.abcd; // return false
Lalnuntluanga Chhakchhuak
la source
3

En quelques mots: rattrapez l'exception.

Je suis vraiment surpris que personne n'ait encore répondu ou commenté Exception Catch sur ce post.

Détail: voici un exemple où j'essaie de faire correspondre une fonction qui est préfixée par mask_ et suffixée par le champ de formulaire "nom". Lorsque JavaScript ne trouve pas la fonction, il doit lancer une ReferenceError que vous pouvez gérer comme vous le souhaitez dans la section catch.

function inputMask(input) {
  try {
    let maskedInput = eval("mask_"+input.name);

    if(typeof maskedInput === "undefined")
        return input.value;
    else
        return eval("mask_"+input.name)(input);

  } catch(e) {
    if (e instanceof ReferenceError) {
      return input.value;
    }
  }
}

Matteus Barbosa
la source
2

Sans conditions

me.onChange=function(){};

function getID( swfID ){
     if(navigator.appName.indexOf("Microsoft") != -1){
          me = window[swfID];
     }else{
          me = document[swfID];
     }
}

function js_to_as( str ){
     me.onChange(str);
}
Itay Moav -Malimovka
la source
2

Je soupçonne que la charge men'est pas correctement affectée.

Le déplacement de l'appel get_ID dans l'événement onclick devrait en prendre soin.

Évidemment, vous pouvez piéger davantage comme mentionné précédemment:

function js_to_as( str) {
  var me = get_ID('jsExample');
  if (me && me.onChange) {
    me.onChange(str);
  }
}
wombleton
la source
2

Je vérifie toujours comme ça:

if(!myFunction){return false;}

il suffit de le placer avant tout code utilisant cette fonction

el Dude
la source
2

J'ai eu le cas où le nom de la fonction variait selon une variable (var 'x' dans ce cas) ajoutée au nom de la fonction. Cela marche:

if ( typeof window['afunction_'+x] === 'function' ) { window['afunction_'+x](); } 
Sebastian H
la source
2

Ce simple code jQuery devrait faire l'affaire:

if (jQuery.isFunction(functionName)) {
    functionName();
}
mainak chakraborty
la source
2

J'ai essayé la réponse acceptée; toutefois:

console.log(typeof me.onChange);

renvoie «non défini». J'ai remarqué que la spécification indique un événement appelé «onchange» au lieu de «onChange» (notez le camelCase).

La modification de la réponse acceptée d'origine aux éléments suivants a fonctionné pour moi:

if (typeof me.onchange === "function") { 
  // safe to use the function
}
Alexander Fuchs
la source
2

Si vous recherchez une fonction qui est un plugin jQuery, vous devez utiliser $ .fn.myfunction

if (typeof $.fn.mask === 'function') {
    $('.zip').mask('00000');
}
Lucas Bustamante
la source
2

J'ai également recherché une solution élégante à ce problème. Après mûre réflexion, j'ai trouvé cette approche meilleure.

const func = me.onChange || (str => {}); func(str);

julien
la source
Si vous optez pour minimalizm, vous pouvez également faire ceci: (me.onChange||(_=>_))()exécutera la fonction si elle existe, sinon ne fera rien.
JSideris
Il vaut mieux me.onChange && me.onChange()éviter de définir une fonction void.
necrifede le
2

Javascript moderne à la rescousse!

Cela pourrait ne pas avoir de grandes chances d'être vu avec la longue liste de réponses, mais cela est maintenant résolu * au niveau de la langue avec la nouvelle syntaxe de chaînage facultative

me.onChange?.(str)

C'est aussi simple que cela - onChangen'est appelé que s'il existe .

S'il onChangen'existe pas, rien ne se passe et l'expression revient undefined- donc si elle a une valeur de retour que vous utiliseriez autrement, vous pouvez simplement vérifier cette valeur !== undefinedavant de continuer.

Mise en garde de cas limite - si onChange ne existons , mais en est pas une fonction, vous obtenez un TypeError. C'est comme vous vous en doutez, c'est la même chose que d'essayer d'appeler une non-fonction en tant que fonction, mais il convient de souligner explicitement que le chaînage facultatif ne fait aucune magie pour que cela disparaisse.

* Eh bien, techniquement parlant, le chaînage facultatif est toujours une proposition de l'étape 4 TC39, il n'est donc pas encore dans la spécification ECMAScript, mais l'étape 4 signifie qu'il est finalisé et que son inclusion est essentiellement garantie, il attend juste qu'une nouvelle version soit livrée. Vous pouvez utiliser la syntaxe dans sa version finale aujourd'hui via Babel avec confiance qu'elle ne changera pas. C'est même en Typographie!

davnicwil
la source
1

Voici une solution simple et fonctionnelle pour vérifier l' existence d'une fonction et déclencher cette fonction dynamiquement par une autre fonction;

Fonction de déclenchement

function runDynamicFunction(functionname){ 

    if (typeof window[functionname] == "function") { //check availability

        window[functionname]("this is from the function it"); // run function and pass a parameter to it
    }
}

et vous pouvez maintenant générer dynamiquement la fonction en utilisant peut-être php comme celui-ci

function runThis_func(my_Parameter){

    alert(my_Parameter +" triggerd");
}

vous pouvez maintenant appeler la fonction à l'aide d'un événement généré dynamiquement

<?php

$name_frm_somware ="runThis_func";

echo "<input type='button' value='Button' onclick='runDynamicFunction(\"".$name_frm_somware."\");'>";

?>

le code HTML exact dont vous avez besoin est

<input type="button" value="Button" onclick="runDynamicFunction('runThis_func');">
Aylian Craspa
la source
0
    function sum(nb1,nb2){

       return nb1+nb2;
    }

    try{

      if(sum() != undefined){/*test if the function is defined before call it*/

        sum(3,5);               /*once the function is exist you can call it */

      }

    }catch(e){

      console.log("function not defined");/*the function is not defined or does not exists*/
    }
Ir Calif
la source
0

Et puis il y a ceci ...

( document.exitPointerLock || Function )();
Maître James
la source
bonjour Maître, bon, mais que pensez-vous de la capture de l'exception? vérifier ma réponse
Matteus Barbosa
Salut merci pour la note. Votre solution est admirable. J'essaie d'éviter le paradigme «try-catch» chaque fois que possible ou plus facile, ou peut-être qu'il a été implicite / imposé par une aide tierce. 'Eval' est également mal vu pour diverses raisons, comme essayer un autre emballage, ce qui retarde le temps. Il existe des alternatives à eval qui pourraient également «jeter». Je pense que 'new Function (parms, body)' pourrait peut-être vous lancer une erreur, mais je suppose que la question suivante pour moi est la comparaison de vitesse, autre que la meilleure réduction de la taille du code (implique plus rapide pour moi). [Hmm, ça a l'air nouveau. Je ne l'ai pas essayé jsben.ch]
Master James
mmm rly point intéressant d'appeler une nouvelle fonction à la place. n'hésitez pas à soumettre vos suggestions de modifications à ma réponse. merci beaucoup
Matteus Barbosa
Je veux dire que même en bash, utiliser «source myScript.sh» vous permettra «d'exporter» via des alias, etc. c'est comme si les classes et les bibliothèques avaient toujours été une propriété inhérente à tout code. Vous devriez avoir un code de vérification d'interprète js s'il n'est pas sanctionné à coup sûr. J'en ai construit une dans une seule fonction, ce qui est un autre défi amusant pour aider à comprendre la nature axiomatique la plus simple du code, et même une exécution n'est au-delà de la capacité de personne.
Master James
0

Essaye celui-là:

Window.function_exists=function(function_name,scope){
//Setting default scope of none is provided
If(typeof scope === 'undefined') scope=window;
//Checking if function name is defined
If (typeof function_name === 'undefined') throw new 
Error('You have to provide an valid function name!');
//The type container
var fn= (typeof scope[function_name]);
//Function type
If(fn === 'function') return true;
//Function object type
if(fn.indexOf('function')!== false) return true; 
return false;
}

Sachez que j'ai écrit ceci avec mon téléphone portable Peut contenir des problèmes en majuscules et / ou d'autres corrections nécessaires comme par exemple le nom des fonctions

Si vous voulez qu'une fonction comme PHP vérifie si la var est définie:

Window.isset=function (variable_con){
If(typeof variable_con !== 'undefined') return true;
return false;
}
SkullWritter
la source
0

Pour illustrer les réponses précédentes, voici un rapide extrait JSFiddle:

function test () {
console.log()

}

console.log(typeof test) // >> "function"

// implicit test, in javascript if an entity exist it returns implcitly true unless the element value is false as :
// var test = false
if(test){ console.log(true)}
else{console.log(false)}

// test by the typeof method
if( typeof test === "function"){ console.log(true)}
else{console.log(false)}


// confirm that the test is effective : 
// - entity with false value
var test2 = false
if(test2){ console.log(true)}
else{console.log(false)}

// confirm that the test is effective :
// - typeof entity
if( typeof test ==="foo"){ console.log(true)}
else{console.log(false)}

/* Expected :
function
true 
true 
false
false
*/

HoCo_
la source
0
// just pass your tested function name instead of myFunctionName
if ( $.isFunction($.fn.myFunctionName) ) {
    console.log( 'write your code here.' );
}
Zabid Ahmed
la source