Wie überprüfe ich, ob eine Funktion in JavaScript vorhanden ist?

533

Mein Code ist

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

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

Manchmal wird mein onChangejedoch nicht geladen. Firebug-Fehler mit

me.onChange ist keine Funktion

Ich möchte mich elegant verschlechtern, da dies nicht das wichtigste Merkmal in meinem Programm ist. typeofgibt den gleichen Fehler.

Irgendwelche Vorschläge, wie Sie sicherstellen können, dass es existiert und dann nur ausgeführt werden onChange?

(Keine der folgenden Methoden außer versuchen, eine Arbeit zu fangen)

Alec Smart
quelle
1
@SteveChambers Das habe ich getan. Danke, dass du mich erinnerst.
Alec Smart
Fang die Ausnahme. Überprüfen Sie meine Antwort
Matteus Barbosa

Antworten:

1225

Versuchen Sie so etwas:

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

oder noch besser (gemäß UpTheCreek-Kommentar)

if (typeof me.onChange === "function") { 
    // safe to use the function
}
Andrew Hare
quelle
249
=== 'Funktion' wäre besser als! = 'undefiniert'
UpTheCreek
3
@ James, weil diese Anweisung tatsächlich eine undefinedAusnahme im JavaScript auslöst . Ich versuchte es.
Mike Perrenoud
8
@UpTheCreek, es wäre als allgemeine Lösung etwas gefährlich, da ältere Versionen des IE bestimmte Funktionen als Objekte behandeln, z typeof window.alert === 'object'.
Noyo
1
Warum nicht einfach benutzen if (me.onChange) { // do something }?
BornToCode
3
@BornToCode, da dann me.onChangealles ausgewertet werden kann true, nicht unbedingt eine Funktion (z. B. ein Boolescher Wert, eine Zeichenfolge usw.). Zum Beispiel siehe jsfiddle.net/j5KAF/1
Ohad Schneider
108

Ich hatte dieses Problem.

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

hat immer wieder einen Referenzfehler ausgegeben, wenn obj undefiniert war.

Am Ende habe ich folgendes gemacht:

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

Ein Kollege hat mich darauf hingewiesen, dass es natürlich überflüssig ist , zu prüfen, ob dies der !== 'undefined'Fall === 'function'ist.

Einfacher:

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

Viel sauberer und funktioniert super.

Mischa Nasledov
quelle
1
Hat jemand eine Idee, warum das erste Code-Snippet wirft ReferenceError? Das erscheint mir unlogisch.
sagte Fagan
@saidfagan Siehe die Definition von ReferenceError developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Misha Nasledov
das funktioniert bei mir
NewBie1234
1
Gibt es ein Motiv, warum die Art von obj == 'Funktion' nicht ausreicht? ;-) Erinnerung: Ein strikter Gleichheitstestoperator ist nur dann sinnvoll, wenn der statische Operand leer oder null oder 0 ist oder einem solchen Cast-Amalgame unterliegt.
Fabien Haddadi
16

Wenn Sie eval verwenden, um eine Zeichenfolge in eine Funktion zu konvertieren, und überprüfen möchten, ob diese eval'd-Methode vorhanden ist, sollten Sie typeof und Ihre Funktionszeichenfolge in einer Bewertung verwenden :

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

Nicht diese umkehren und versuchen typeof auf eval . Wenn Sie dies tun, wird ein ReferenceError ausgelöst:

var functionString = "nonexsitantFunction"
typeof(eval(functionString)) // returns ReferenceError: [function] is not defined
Dhulihan
quelle
21
eval == böse;)
Yeti
1
Es mag böse sein, aber dies ist sehr hilfreich, wenn sich der Funktionsname in einer Variablen befindet.
Luke Cousins
8
Sie können dies ohne Bewertung tun. Beispiel:var a = 'alert'; window[a]('it works');
Zennin
15

Wie wäre es mit:

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

z.B

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

oder wie für Ihren Fall:

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

Siehe MDN-Dokumente .

Nasser Al-Wohaibi
quelle
Aber diese Lösung funktioniert nicht jedes Mal :( Wenn ich zum Beispiel wissen möchte, dass es sich um eine lastIndexOf()Zeichenfolge handelt (wir wissen, das heißt, aber theoretisch), ist typeof String().lastIndexOf === "function"sie wahr, aber 'lastIndexOf' in Stringfalsch.
iiic
10

Versuchen Sie typeof- 'undefined'Sagen Sie, dass es 'function'für eine Funktion nicht existiert . JSFiddle für diesen Code

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

Oder als ob:

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

Oder mit einem Rückgabewert in einer einzelnen Zeile:

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

Ich habe dies nicht vorgeschlagen gesehen: me.onChange && me.onChange (str);

Wenn me.onChange undefiniert ist (was der Fall ist, wenn es nicht initiiert wurde), wird der letzte Teil grundsätzlich nicht ausgeführt. Wenn me.onChange eine Funktion ist, wird me.onChange (str) ausgeführt.

Sie können sogar noch weiter gehen und Folgendes tun:

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

falls ich auch asynchron bin.

Samir Alajmovic
quelle
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
quelle
Ihre Lösung ist nicht klar, da sie jQUery enthält, was in diesem Moment meiner Meinung nach seltsam ist. Daher wirft es beim einfachen Testen Fehler auf.
T.Todua
@tazotodua es ist selbsterklärende Funktion. wenn Sie ohne jquery verwenden möchten. Entfernen Sie einfach den && Teil. Dies ist eine zusätzliche Bedingung, um Fehler zu überprüfen und zu vermeiden.
Muhammad Tahir
Kümmert sich der Zustand auf der linken Seite &&um etwas, was der jQuery isFunctionauf der rechten Seite &&nicht tut?
SantiBailors
5

Für mich der einfachste Weg:

function func_exists(fname)
{
  return (typeof window[fname] === 'function');
}
Tu4n3r
quelle
Dies ist die richtige Antwort, weil es eine Saite ist. Ich würde es besser so sagen, if ((typeof window["function_name"] !== 'undefined') && ((typeof window["function_name"] === 'function'))) { return true; } else { return false; }aber es ist eine geringfügige Anpassung
Herr Heelis
4

Ich werde noch einen Schritt weiter gehen, um sicherzustellen, dass die Eigenschaft tatsächlich eine Funktion ist

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

Ich benutze diese Methode gerne:

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

Verwendungszweck:

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

Die Underscore.js-Bibliothek definiert es in der isFunction-Methode wie folgt (die Kommentare deuten darauf hin, dass einige Browserfehler behoben werden können).

typeof obj == 'function' || false

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

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

ODER

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
quelle
1
Bitte eine Erklärung.
Gufran Hasan
In zwei Fällen rufen Sie einfach function_exists mit dem Namen des Funktionsparameters auf, um die Existenz zu überprüfen, und geben bool zurück.
Mohammad Lotfi
3

Setzen Sie ein doppeltes Ausrufezeichen, dh !! vor dem Funktionsnamen, den Sie überprüfen möchten. Wenn es existiert, wird es true zurückgeben.

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

In wenigen Worten: Fangen Sie die Ausnahme.

Ich bin wirklich überrascht, dass noch niemand auf Exception Catch in diesem Beitrag geantwortet oder kommentiert hat.

Detail: Hier ist ein Beispiel, in dem ich versuche, eine Funktion zu finden, der mask_ vorangestellt und das Formularfeld "name" angehängt ist. Wenn JavaScript die Funktion nicht findet, sollte es einen ReferenceError auslösen, den Sie im catch-Abschnitt nach Belieben behandeln können.

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
quelle
2

Ohne Bedingungen

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
quelle
2

Ich würde vermuten, dass medie Onload nicht richtig zugewiesen wird.

Das Verschieben des get_ID-Aufrufs in das onclick-Ereignis sollte sich darum kümmern.

Natürlich können Sie wie bereits erwähnt weiter fangen:

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

Ich überprüfe immer so:

if(!myFunction){return false;}

Platzieren Sie es einfach vor einem Code, der diese Funktion verwendet

el Dude
quelle
2

Ich hatte den Fall, dass der Name der Funktion gemäß einer Variablen (in diesem Fall var 'x') variierte, die dem Funktionsnamen hinzugefügt wurde. Das funktioniert:

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

Dieser einfache jQuery-Code sollte den Trick machen:

if (jQuery.isFunction(functionName)) {
    functionName();
}
Mainak Chakraborty
quelle
2

Ich habe die akzeptierte Antwort versucht; jedoch:

console.log(typeof me.onChange);

gibt 'undefined' zurück. Ich habe festgestellt, dass in der Spezifikation ein Ereignis namens "onchange" anstelle von "onChange" angegeben ist (beachten Sie den camelCase).

Das Ändern der ursprünglich akzeptierten Antwort auf Folgendes hat bei mir funktioniert:

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

Wenn Sie nach einer Funktion suchen, die ein jQuery-Plugin ist, müssen Sie $ .fn.myfunction verwenden

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

Ich habe auch nach einer eleganten Lösung für dieses Problem gesucht. Nach langem Nachdenken fand ich diesen Ansatz am besten.

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

julianisch
quelle
Wenn Sie sich für Minimalismus entscheiden, können Sie auch Folgendes tun: Führt (me.onChange||(_=>_))()die Funktion aus, falls vorhanden, andernfalls wird nichts unternommen.
JSideris
Es ist besser me.onChange && me.onChange()zu verhindern, dass eine Leerfunktion definiert wird.
Nekrifede
2

Modernes Javascript zur Rettung!

Dies könnte nicht eine große Chance hat , mit der langen Liste der Antworten gesehen zu werden, aber das ist jetzt * auf der Sprachebene mit der neuen gelöst Optional Chaining Syntax

me.onChange?.(str)

So einfach ist das - wird onChangenur aufgerufen, wenn es existiert .

Wenn onChangedies nicht vorhanden ist, geschieht nichts und der Ausdruck wird zurückgegeben. undefinedWenn er also einen Rückgabewert hat, den Sie sonst verwenden würden, können Sie diesen Wert einfach überprüfen, !== undefinedbevor Sie fortfahren.

Edge - Fall Nachteil - wenn onChange tut exist aber ist nicht eine Funktion geben Sie eine bekommen TypeError. Dies ist wie zu erwarten, es ist dasselbe wie der Versuch, eine Nichtfunktion als Funktion aufzurufen, aber es sollte ausdrücklich darauf hingewiesen werden, dass die optionale Verkettung keine Magie ausübt, um dies zu beseitigen.

* Nun, technisch gesehen ist die optionale Verkettung immer noch ein TC39-Vorschlag der Stufe 4, daher noch nicht in der ECMAScript-Spezifikation enthalten, aber Stufe 4 bedeutet, dass sie abgeschlossen ist und ihre Aufnahme im Wesentlichen garantiert ist. Sie wartet nur auf den Versand einer neuen Version. Sie können die Syntax in der endgültigen Version heute über Babel mit der Gewissheit verwenden, dass sie sich nicht ändert. Es ist sogar in Typoskript!

davnicwil
quelle
1

Hier ist eine funktionierende und einfache Lösung, um das Vorhandensein einer Funktion zu überprüfen und diese Funktion dynamisch durch eine andere Funktion auszulösen .

Auslöserfunktion

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

und Sie können die Funktion jetzt dynamisch generieren, möglicherweise mit PHP wie diesem

function runThis_func(my_Parameter){

    alert(my_Parameter +" triggerd");
}

Jetzt können Sie die Funktion mit einem dynamisch generierten Ereignis aufrufen

<?php

$name_frm_somware ="runThis_func";

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

?>

Der genaue HTML-Code, den Sie benötigen, ist

<input type="button" value="Button" onclick="runDynamicFunction('runThis_func');">
Aylian Craspa
quelle
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
quelle
0

Und dann ist da noch das ...

( document.exitPointerLock || Function )();
Meister James
quelle
Hallo Meister, guter, aber was denkst du über das Fangen der Ausnahme? Überprüfen Sie meine Antwort
Matteus Barbosa
Hallo danke für den Hinweis. Ihre Lösung ist bewundernswert. Ich versuche, das "Try-Catch" -Paradigma zu vermeiden, wann immer dies möglich oder einfacher ist, oder es wurde möglicherweise von einer Hilfe eines Dritten impliziert / auferlegt. 'Eval' wird auch aus verschiedenen Gründen verpönt, weil man versucht, einen anderen Wrapper zu fangen, so dass sich die Zeit verzögert. Es gibt Alternativen zur Bewertung, die auch "werfen" könnten. Ich denke, 'neue Funktion (Parameter, Körper)' würde Ihnen vielleicht einen Fehler werfen, aber ich denke, die nächste Frage für mich sind Geschwindigkeitsvergleiche, andere als nur die beste Reduzierung der Codegröße (bedeutet für mich schneller). [Hmm das sieht neu aus. Ich habe es nicht versucht jsben.ch]
Master James
mmm rly interessanter Punkt, stattdessen neue Funktion aufzurufen. Fühlen Sie sich frei, Ihre Änderungsvorschläge an meine Antwort zu senden. Vielen Dank
Matteus Barbosa
Ja, ich meine, selbst in Bash mit 'source myScript.sh' können Sie über Aliase usw. 'exportieren'. Es ist, als ob Klassen und Bibliotheken immer eine inhärente Eigenschaft von Code gewesen wären. Sie sollten einen js-Interpreter-Prüfcode haben, wenn dieser nicht sicher genehmigt wurde. Ich habe eine Funktion in einer einzigen Funktion integriert. Dies ist eine weitere unterhaltsame Herausforderung, um die einfachste axiomatische Natur von Code zu verstehen, und selbst eine Laufzeit ist für niemanden unerreichbar.
Meister James
0

Probier diese:

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

Beachten Sie, dass ich dies mit meinem Handy geschrieben habe. Möglicherweise enthält es einige Probleme in Großbuchstaben und / oder andere Korrekturen, die erforderlich sind, z. B. der Name der Funktion

Wenn Sie möchten, dass eine Funktion wie PHP überprüft, ob die Variable gesetzt ist:

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

Um die vorhergehenden Antworten zu veranschaulichen, hier ein kurzer JSFiddle-Ausschnitt:

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_
quelle
0
// just pass your tested function name instead of myFunctionName
if ( $.isFunction($.fn.myFunctionName) ) {
    console.log( 'write your code here.' );
}
Zabid Ahmed
quelle