Come verificare se la funzione esiste in JavaScript?


534

Il mio codice è

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

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

Tuttavia, a volte il mio onChangenon si carica. Errori Firebug con

me.onChange non è una funzione

Voglio degradare con grazia perché questa non è la caratteristica più importante nel mio programma. typeofdà lo stesso errore.

Eventuali suggerimenti su come accertarsi che esista e quindi eseguire solo onChange ?

(Nessuno dei metodi seguenti, tranne provare a catturare un'opera)


1
@SteveChambers L'ho fatto. Grazie per avermelo ricordato.
Alec Smart il


cogliere l'eccezione. controlla la mia risposta
Matteus Barbosa,

Risposte:


1227

Prova qualcosa del genere:

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

o meglio ancora (come da commento di UpTheCreek votato)

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

249
=== 'funzione' sarebbe meglio di! = 'undefined'
UpTheCreek

3
@James, perché questa affermazione in realtà genera undefinedun'eccezione in JavaScript. L'ho provato.
Mike Perrenoud,

8
@UpTheCreek, sarebbe un po 'pericoloso come soluzione generale poiché le versioni precedenti di IE trattano determinate funzioni come oggetti, ad es typeof window.alert === 'object'.
Noyo,

1
Perché non usare solo if (me.onChange) { // do something }?
BornToCode

3
@BornToCode perché allora me.onChangepotrebbe essere qualcosa che sta valutando true, non necessariamente una funzione (ad esempio potrebbe essere un valore booleano, una stringa, ecc.). Ad esempio, vedi jsfiddle.net/j5KAF/1
Ohad Schneider il

108

Ho avuto questo problema

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

continuava a generare un errore di riferimento se obj non era definito.

Alla fine ho fatto quanto segue:

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

Un collega mi ha fatto notare che controllando se è !== 'undefined'e poi=== 'function' è ridondante, ovviamente.

Più semplice:

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

Molto più pulito e funziona alla grande.


1
Qualcuno ha idea del motivo per cui viene lanciato il primo frammento di codice ReferenceError? Mi sembra illogico.
saidfagan il

@saidfagan Vedi la definizione di ReferenceError developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Misha Nasledov

questo funziona per me
NewBie1234

1
Qualche motivo per cui typeof obj == 'function' sarebbe insufficiente? ;-) Promemoria: l'operatore del test di uguaglianza rigorosa ha senso solo quando l'operando statico è vuoto o nullo o 0 o soggetto a un cast di giochi come questo.
Fabien Haddadi,

16

Se stai usando eval per convertire una stringa in funzione e vuoi controllare se esiste questo metodo di valutazione, ti consigliamo di usare typeof e la tua stringa di funzione all'interno di un eval :

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

Non invertire questo e cercare un typeof su eval . Se lo fai, verrà lanciato un ReferenceError:

var functionString = "nonexsitantFunction"
typeof(eval(functionString)) // returns ReferenceError: [function] is not defined

21
eval == evil;)
Yeti

1
Potrebbe essere male, ma questo è molto utile quando il nome della funzione è in una variabile.
Luke Cousins,

8
Puoi farlo senza valutazione. Esempio:var a = 'alert'; window[a]('it works');
zennin,

15

Che ne dite di:

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

per esempio

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

o come nel tuo caso:

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

Vedi i documenti MDN .


ma questa soluzione non funziona ogni volta :( per esempio se voglio sapere che c'è lastIndexOf()nella stringa (sappiamo, cioè teoricamente) typeof String().lastIndexOf === "function"è vera, ma 'lastIndexOf' in Stringè falsa.
iiic

10

Prova typeof: cerca 'undefined'di dire che non esiste, 'function'per una funzione. JSFiddle per questo codice

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

O come se:

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

O con un valore di ritorno, su una sola riga:

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

9

Non ho visto questo suggerito: me.onChange && me.onChange (str);

Fondamentalmente se me.onChange è indefinito (come sarà se non è stato avviato), non eseguirà quest'ultima parte. Se me.onChange è una funzione, eseguirà me.onChange (str).

Puoi anche andare oltre e fare:

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

nel caso in cui anche io sia asincrono.


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

la tua soluzione non è chiara, poiché contiene jQUery, il che è strano in questo momento penso, quindi genera errori quando si esegue un semplice test.
T.Todua,

@tazotodua è una funzione autoesplicativa. se si desidera utilizzare senza jquery. basta rimuovere la parte &&. questa è una condizione aggiuntiva per controllare ed evitare errori.
Muhammad Tahir,

La condizione sul lato sinistro del si &&prende cura di qualcosa che il jQuery si isFunctiontrova sul lato destro del &&no?
SantiBailors,

5

Per me il modo più semplice:

function func_exists(fname)
{
  return (typeof window[fname] === 'function');
}

questa è la risposta corretta, perché è una stringa litterale .. Direi che è meglio così, if ((typeof window["function_name"] !== 'undefined') && ((typeof window["function_name"] === 'function'))) { return true; } else { return false; }ma è un piccolo aggiustamento
Heelis,

4

Farò un ulteriore passo per assicurarmi che la proprietà sia effettivamente una funzione

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

Mi piace usare questo metodo:

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

Uso:

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

O

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
Per favore, qualche spiegazione.
Gufran Hasan,

In due casi, è sufficiente chiamare function_exists con il nome del parametro della funzione per verificare l'esistenza, restituisce bool.
Mohammad Lotfi,

3

Metti doppio punto esclamativo cioè !! prima del nome della funzione che si desidera verificare. Se esiste, tornerà vero.

function abc(){
}
!!window.abc; // return true
!!window.abcd; // return false

3

In poche parole: cogliere l'eccezione.

Sono davvero sorpreso che nessuno abbia ancora risposto o commentato in merito a Exception Catch su questo post.

Dettaglio: Ecco un esempio in cui provo ad abbinare una funzione che è preceduta da mask_ e suffissata dal campo del modulo "name". Quando JavaScript non trova la funzione, dovrebbe generare un ReferenceError che puoi gestire come desideri nella sezione 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

Senza condizioni

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

Sospetterei che menon viene assegnato correttamente onload.

Lo spostamento della chiamata get_ID nell'evento onclick dovrebbe occuparsene.

Ovviamente puoi intrappolare ulteriormente come precedentemente menzionato:

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

2

Controllo sempre così:

if(!myFunction){return false;}

posizionalo prima di qualsiasi codice che utilizza questa funzione


2

Ho avuto il caso in cui il nome della funzione variava in base a una variabile (var 'x' in questo caso) aggiunta al nome della funzione. Questo funziona:

if ( typeof window['afunction_'+x] === 'function' ) { window['afunction_'+x](); } 

2

Questo semplice codice jQuery dovrebbe fare il trucco:

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

2

Ho provato la risposta accettata; però:

console.log(typeof me.onChange);

restituisce "non definito". Ho notato che la specifica indica un evento chiamato 'onchange' invece di 'onChange' (notare il camelCase).

La modifica della risposta originale accettata al seguente ha funzionato per me:

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

2

Se stai cercando una funzione che è un plugin jQuery, devi usare $ .fn.myfunction

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

2

Ho anche cercato una soluzione elegante a questo problema. Dopo molte riflessioni, ho trovato questo approccio migliore.

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


Se stai cercando minimalizm, puoi anche farlo: (me.onChange||(_=>_))()eseguirà la funzione se esiste, altrimenti non farà nulla.
JSideris,

È meglio me.onChange && me.onChange()evitare di definire una funzione nulla.
necrifede il

2

Javascript moderno per il salvataggio!

Questo potrebbe non avere grandi probabilità di essere visto con la lunga lista di risposte, ma questo è ora risolto * a livello di lingua con la nuova sintassi di Chaining opzionale

me.onChange?.(str)

È così semplice: onChangeviene chiamato solo se esiste .

Se onChangenon esiste, non succede nulla e l'espressione ritorna undefined, quindi se ha un valore di ritorno che altrimenti utilizzeresti, puoi semplicemente controllare questo valore !== undefinedprima di continuare.

Bordo caso avvertimento - se onChange lo fa esistere, ma è non è una funzione, si ottiene unTypeError . Questo è come ti aspetteresti, è lo stesso che provare a chiamare qualsiasi non funzione come funzione, ma vale la pena sottolineare esplicitamente che il concatenamento opzionale non fa alcuna magia per farla sparire.

* Beh, tecnicamente parlando, il concatenamento opzionale è ancora una proposta TC39 della fase 4, quindi non è ancora nelle specifiche ECMAScript, ma la fase 4 significa che è finalizzata e la sua inclusione è sostanzialmente garantita, sta solo aspettando che venga spedita una nuova versione. Puoi usare la sintassi nella sua versione finale oggi tramite Babel con la certezza che non cambierà. È persino in Typescript!


1

Ecco una soluzione semplice e funzionante per verificare l' esistenza di una funzione e attivarla dinamicamente da un'altra funzione;

Funzione di trigger

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

e ora puoi generare dinamicamente la funzione magari usando php in questo modo

function runThis_func(my_Parameter){

    alert(my_Parameter +" triggerd");
}

ora puoi chiamare la funzione usando un evento generato dinamicamente

<?php

$name_frm_somware ="runThis_func";

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

?>

l'esatto codice HTML di cui hai bisogno è

<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

E poi c'è questo ...

( document.exitPointerLock || Function )();

ciao Maestro, bravo, ma che ne pensi di cogliere l'eccezione? controlla la mia risposta
Matteus Barbosa,

Ciao grazie per la nota. La tua soluzione è ammirevole. Cerco di evitare il paradigma del "tentativo di catturare" quando possibile o più facile, o forse è stato implicito / imposto da un aiuto di terze parti. 'Eval' è anche disapprovato per vari motivi: uno è come cercare di catturare un altro wrapper, quindi i ritardi. Ci sono alternative alla valutazione che potrebbero anche "lanciare". Penso che la "nuova funzione (parms, body)" potrebbe darti un errore, ma immagino che la domanda successiva per me sia il confronto della velocità, oltre alla migliore riduzione della dimensione del codice (implica più velocemente per me). [Hmm questo sembra nuovo. Non l'ho provato jsben.ch]
Master James

Invece, è interessante notare come chiamare una nuova funzione. sentiti libero di inviare i tuoi suggerimenti di modifica alla mia risposta. grazie mille
Matteus Barbosa,

Ya intendo anche se bash usando "source myScript.sh" ti permetterà di "esportare" tramite alias ecc. È come se le classi e le librerie siano sempre state una proprietà intrinseca di qualsiasi codice. Dovresti avere un codice di controllo dell'interprete js se non è stato sanzionato di sicuro. Ne ho creato uno in un'unica funzione, che è un'altra sfida divertente per aiutare a comprendere la più semplice natura assiomatica del codice, e persino un tempo di esecuzione non è al di là delle capacità di nessuno.
Master James

0

Prova questo:

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

Essere consapevoli del fatto che ho scritto questo con il mio cellulare Potrebbe contenere alcuni problemi maiuscoli e / o altre correzioni necessarie come ad esempio il nome delle funzioni

Se vuoi una funzione come PHP per verificare se var è impostato:

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

0

Per illustrare le risposte precedenti, qui un breve frammento di 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.' );
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.