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)


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
}

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.


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

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 .


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

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.


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

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

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

3
function js_to_as( str ){
     if (me && me.onChange)
         me.onChange(str);
}

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
}


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';
}

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

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


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

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

2

Je vérifie toujours comme ça:

if(!myFunction){return false;}

il suffit de le placer avant tout code utilisant cette fonction


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](); } 

2

Ce simple code jQuery devrait faire l'affaire:

if (jQuery.isFunction(functionName)) {
    functionName();
}

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
}

2

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

if (typeof $.fn.mask === 'function') {
    $('.zip').mask('00000');
}

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


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!


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

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

0

Et puis il y a ceci ...

( document.exitPointerLock || Function )();

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

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


0
// just pass your tested function name instead of myFunctionName
if ( $.isFunction($.fn.myFunctionName) ) {
    console.log( 'write your code here.' );
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.