JavaScript'te işlevin var olup olmadığını nasıl kontrol edebilirim?


533

Kodum

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

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

Ancak, bazen benim onChangeyüklenmiyor. Firebug hataları

me.onChange bir işlev değildir

Programımın en önemli özelliği olmadığı için incelikle düşürmek istiyorum. typeofaynı hatayı verir.

Var olduğundan emin olmak ve sonra sadece yürütmek için herhangi bir öneriniz var onChangemı?

(Aşağıdaki yöntemlerden hiçbiri bir çalışmayı yakalamayı deneyin hariç)


1
@SteveChambers Bunu yaptım. Bana hatırlattığın için teşekkür ederim.
Alec Smart


İstisna yakalamak. cevabımı kontrol et
Matteus Barbosa

Yanıtlar:


1225

Bunun gibi bir şey deneyin:

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

or better yet (UpTheCreek'e göre oylanan yorum)

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

249
=== 'işlevi' daha iyi olurdu! = 'undefined'
UpTheCreek

3
@James, çünkü bu ifade aslında undefinedJavaScript'te bir istisna atar . Denedim.
Mike Perrenoud

8
@UpTheCreek, IE'nin eski sürümleri belirli işlevleri nesne olarak ele aldığından, genel bir çözüm olarak biraz tehlikeli olacaktır typeof window.alert === 'object'.
Noyo

1
Neden sadece kullanmıyorsunuz if (me.onChange) { // do something }?
BornToCode

3
@BornToCode, o zaman bir işlevi değil, me.onChangedeğerlendirmek için herhangi bir şey olabilir true(örneğin bir boolean, dize, vb.). Örneğin, bkz. Jsfiddle.net/j5KAF/1
Ohad Schneider

108

Bu sorunu yaşadım.

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

nesne tanımlanmamışsa bir referans hatası vermeye devam etti.

Sonunda aşağıdakileri yaptım:

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

Bir meslektaşım bu kadar olmadığını kontrol o bana işaret !== 'undefined'sonra ve === 'function'tabii ki gereksiz olduğunu.

Daha basit:

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

Çok daha temiz ve harika çalışıyor.


1
İlk kod pasajının neden atıldığı hakkında bir fikri olan var ReferenceErrormı? Bana mantıksız geliyor.
saidfagan


Bu benim için çalışıyor
NewBie1234

1
Herhangi bir sebep neden typeof obj == 'function' yetersiz olurdu? ;-) Hatırlatma: katı eşitlik testi operatörü sadece statik işlenen boş veya boş veya 0 olduğunda veya böyle bir döküm amalgame tabi olduğunda mantıklı.
Fabien Haddadi

16

Bir dizeyi işleve dönüştürmek için eval kullanıyorsanız ve bu değerlendirilen yöntemin var olup olmadığını kontrol etmek istiyorsanız, bir eval içinde typeof ve function dizenizi kullanmak istersiniz :

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

Bu tersine çevirmek ve bir kalkmayın typeof üzerinde eval . Eğer bir ReferenceError atılacaksa:

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

21
eval == kötü;)
Yeti

1
Kötü olabilir, ancak işlev adı bir değişkende olduğunda bu çok yararlıdır.
Luke Cousins

8
Bunu eval olmadan yapabilirsiniz. Örnek:var a = 'alert'; window[a]('it works');
zennin

15

Nasıl olur:

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

Örneğin

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

veya davanız için:

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

Bkz. MDN belgeleri .


ancak bu çözüm her zaman işe yaramıyor :( örneğin lastIndexOf()dize içinde olduğunu bilmek istiyorsam (biliyoruz, yani teorik olarak) typeof String().lastIndexOf === "function"bu doğru, ama 'lastIndexOf' in Stringyanlış.
iiic

10

Deneyin typeof- Bir işlev için 'undefined'var olmadığını söylemeye çalışın 'function'. Bu kod için JSFiddle

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

Veya bir if olarak:

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

Veya tek bir satırda bir dönüş değeriyle:

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

9

Bunun önerdiğini görmedim: me.onChange && me.onChange (str);

Temel olarak, eğer me.onChange tanımlanmamışsa (başlatılmamışsa), sonraki kısmı yürütmez. Me.onChange bir işlevse, me.onChange (str) öğesini çalıştırır.

Hatta daha ileri gidip şunları yapabilirsiniz:

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

benim de async olması durumunda.


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

senin çözüm şu anda garip jQUery, containt olarak açık değil bence, bu yüzden basit test zaman hatalar atar.
T.Todua

@tazotodua kendi kendini açıklayan bir işlevdir. jquery olmadan kullanmak istiyorsanız. && parçasını kaldırmanız yeterlidir. bu, kontrol etmek ve hataları önlemek için ekstra bir koşuldur.
Muhammed Tahir

Sol taraftaki durum &&jQuery'nin isFunctionsağ tarafında &&olmayan bir şeye dikkat ediyor mu?
SantiBailors

5

Benim için en kolay yol:

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

bu doğru cevap, çünkü bu bir dizgi okuryazarlığı .. Bunu daha iyi söyleyebilirim if ((typeof window["function_name"] !== 'undefined') && ((typeof window["function_name"] === 'function'))) { return true; } else { return false; }ama küçük bir düzenleme
Bay Heelis

4

Özelliğin gerçekten bir işlev olduğundan emin olmak için 1 adım daha ileri gideceğim

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

Bu yöntemi kullanmayı seviyorum:

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

Kullanımı:

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

VEYA

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
Lütfen, biraz açıklama.
Gufran Hasan

İki durumda da, yalnızca çağrı function_exists varlığını kontrol etmek fonksiyon parametresinin adı ile, döner bool.
Mohammad Lotfi

3

Çift ünlem işareti koy !! kontrol etmek istediğiniz işlev adından önce. Varsa, doğru dönecektir.

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

3

Birkaç kelimeyle: istisnayı yakalayın.

Bu yayında henüz Exception Catch hakkında kimsenin cevap vermediği veya yorum yapmadığı için gerçekten şaşırdım.

Detay: Burada mask_ ile önek ve "isim" form alanı ile son eklenmiş bir işlevi eşleştirmek çalışıyorum bir örnek gider. JavaScript işlevi bulamadığında , yakalama bölümünde istediğiniz gibi işleyebileceğiniz bir ReferenceError atmalıdır.

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

Koşulsuz

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

meOnload doğru atanan şüpheli olur .

Get_ID çağrısını onclick etkinliğine taşımak, bununla ilgilenmelidir.

Açıkçası, daha önce belirtildiği gibi daha fazla tuzak yapabilirsiniz:

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

2

Her zaman böyle kontrol ederim:

if(!myFunction){return false;}

sadece bu işlevi kullanan herhangi bir kodun önüne yerleştirin


2

İşlev adının işlev adına eklenen bir değişkene (bu durumda var 'x') göre değiştiği bir durum vardı. Bu çalışıyor:

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

2

Bu basit jQuery kodu hile yapmalıdır:

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

2

Kabul edilen cevabı denedim; ancak:

console.log(typeof me.onChange);

'tanımsız' döndürür. Spesifikasyonun 'onChange' yerine 'onchange' adlı bir olayı bildirdiğini fark ettim (camelCase'e dikkat edin).

Kabul edilen orijinal yanıtı aşağıdaki şekilde değiştirmek benim için çalıştı:

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

2

Bir jQuery eklentisi olan bir işlevi kontrol ediyorsanız, $ .fn.myfunction kullanmanız gerekir

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

2

Ayrıca bu soruna zarif bir çözüm arıyordum. Çok fazla düşünmeden sonra, bu yaklaşımı en iyi buldum.

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


Minimalizm için gidiyorsanız, bunu da yapabilirsiniz: (me.onChange||(_=>_))()Varsa işlevi yürütür, aksi takdirde hiçbir şey yapmaz.
JSideris

me.onChange && me.onChange()Bir boşluk fonksiyonunun tanımlanmasını önlemek daha iyidir .
necrifede

2

Kurtarmaya Modern Javascript!

Bu, uzun cevap listesiyle görülme şansı olmayabilir, ancak şimdi yeni İsteğe Bağlı Zincirleme sözdizimi ile dil düzeyinde * çözüldü

me.onChange?.(str)

Bu kadar basit - onChangesadece varsa çağrılır .

Eğer onChangeyoksa, hiçbir şey olmaz ve ifade geri döner undefined- böylece aksi takdirde kullanacağınız bir dönüş değeri varsa, bu değeri kontrol edebilirsiniz.!== undefined devam etmeden önce .

Kenar kasası uyarısı - varsa onChange , ancak bir işlev değilse ,TypeError . Bu beklediğiniz gibi, herhangi bir işlevsizliği bir işlev olarak çağırmaya çalışmakla aynıdır, ancak İsteğe Bağlı Zincirleme'nin bunu ortadan kaldırmak için herhangi bir sihir yapmadığını açıkça belirtmeye değer.

* Teknik olarak konuşan İsteğe Bağlı Zincirleme hala bir aşama 4 TC39 önerisidir, bu yüzden henüz ECMAScript spesifikasyonunda yer almamaktadır, ancak aşama 4 tamamlandığı ve dahil edilmesinin esas olarak garanti edildiği anlamına gelir, sadece yeni bir versiyonun gönderilmesini beklemektedir. Sözdizimini bugün son sürümünde, Babel üzerinden, değişmeyeceğinden güvenle kullanabilirsiniz. Dizgi yazısında bile!


1

İşte bir işlevin varlığını kontrol etmek ve bu işlevi başka bir işlevle dinamik olarak tetiklemek için çalışan ve basit bir çözüm ;

Tetikleme işlevi

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

ve şimdi işlevi php kullanarak böyle dinamik olarak üretebilirsiniz

function runThis_func(my_Parameter){

    alert(my_Parameter +" triggerd");
}

şimdi dinamik olarak oluşturulan olayı kullanarak işlevi çağırabilirsiniz

<?php

$name_frm_somware ="runThis_func";

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

?>

tam ihtiyacınız olan HTML kodu

<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

Ve sonra bu var ...

( document.exitPointerLock || Function )();

merhaba Üstat, iyi olan, ama İstisna'yı yakalamak hakkında ne düşünüyorsun? cevabımı kontrol et
Matteus Barbosa

Merhaba not için teşekkürler. Çözümünüz takdire şayan. Mümkün olduğunca veya daha kolay 'try-catch' paradigmasından kaçınmaya çalışıyorum, ya da belki de 3. taraf bir yardımla ima ediliyor / dayatılıyor. 'Eval' da çeşitli nedenlerden ötürü kaşlarını çatırmaya çalışır, böylece zaman geciktirir. Değerlendirmek için de 'fırlatabilecek' alternatifler vardır. Sanırım 'yeni Fonksiyon (parms, vücut)' size bir hata fırlatabilir, ama benim için bir sonraki soru hız karşılaştırmaları, diğer sadece en iyi kod boyutu küçültme (benim için daha hızlı anlamına geliyor) sanırım. [Hmm bu yeni görünüyor. Ben denemedim jsben.ch]
Usta James

mmm yerine yeni Fonksiyon çağırmak için ilginç bir nokta. değişiklik önerilerinizi cevabıma göndermekten çekinmeyin. çok teşekkürler
Matteus Barbosa

Ya da bash'de bile 'kaynak myScript.sh' kullanarak takma adlar aracılığıyla 'dışa aktarmanıza' izin verir. Sınıflar ve kütüphaneler her zaman her kodun doğal bir özelliği olmuştur. Emin olunmazsa, bir js tercüman kontrol koduna sahip olmalısınız. Kodun en basit aksiyomatik doğasını anlamaya yardımcı olacak başka bir eğlenceli zorluk olan tek bir işlevde bir tane inşa ettim ve bir çalışma süresi bile kimsenin yeteneğinin ötesinde değil.
Usta James

0

Bunu dene:

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

Bunu cep telefonumla yazdığımı unutmayın Bazı büyük sorunlar ve / veya işlev adı gibi gerekli diğer düzeltmeleri içerebilir

PHP gibi bir fonksiyonun var olup olmadığını kontrol etmesini istiyorsanız:

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

0

Önceki yanıtları göstermek için, burada hızlı bir JSFiddle snippet'i:

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.' );
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.