Tırnak ve parantez içeren veya içermeyen setTimeout arasındaki fark


240

JavaScript öğreniyorum ve son zamanlarda JavaScript zamanlama olaylarını öğrendim. Ben yaklaşık öğrendiğimde setTimeoutde W3Schools'da , daha önce girmek yoktu garip figür ettim. Çift tırnak işareti kullanıyorlar ve sonra işlevi çağırıyorlar.

Misal:

setTimeout("alertMsg()", 3000);

JavaScript çift ve tek tırnak bir dize anlamına biliyorum.

Ayrıca aynı şekilde yapabileceğimi gördüm:

setTimeout(alertMsg, 3000);

Parantez söz konusu olduğunda, parantez olmadan kopyalanır. Tırnakları ve parantezleri kullanırken deliriyorum.

Birisi bana bu üç kullanım yolu arasındaki farkı açıklayabilirse memnun olurum setTimeout:

Parantez ile:

setTimeout("alertMsg()", 3000);

Tırnak işaretleri ve parantez olmadan:

setTimeout(alertMsg, 3000);

Ve üçüncüsü sadece tırnak işaretleri kullanıyor:

setTimeout("alertMsg", 3000);

Not: setTimeoutReferans için daha iyi bir kaynak MDN olacaktır .


5
@ Jefffrey w3fools web sitesi orada içeriğin yanlış olduğunu söylemez, sadece eski olabilir ve bazı yeni şeyler eksik olabilir. Temel şeyler için bir referans olarak (ya da öğrenmek için) kullanmak iyi olmalıdır. İnsanları, w3'ün bir parçası gibi görünmeye çalıştıkları için hayal kırıklığına uğradıklarını anlayabiliyorum, ancak bu içerikten etkilenmiyor. Güzel düzenlenmiş ve noobs için kaymakam net örnekleri ile okunması kolay.
Matthew

14
@Matthew "Yine de, W3Schools'un topluma yanlış bilgilerle zarar verdiğini düşünüyoruz." - ilk üç satır içinde.
Ayakkabı

1
@ Jefffrey evet gördüm ama onlar hakkında ne sevmediklerini açıklamak aşağı aşağıda, "W3Schools sorun" bölümünde, verdikleri üç neden hiçbiri yanlış bilgi ile ilgisi yoktur. Aslında "yanlış" olan hiçbir şeye tek bir örneği yok. Onların şikayetleri, açıkça w3'e bağlı olmadıklarını söylemiyorlar, tanınmayan sertifikalar için ücret alıyorlar ve yeni içerikle hızlı bir şekilde güncellenmiyorlar (örn. Html 5).
Matthew

10
@Matthew, Javascript, SQL veya PHP gibi hassas dillerde eski bilgiler, istekli programcı kitlelerinin mysql_SO soru akışının sadece bir örnek olduğu eski ve potansiyel olarak tehlikeli teknolojilere ( PHP'nin uzantısı gibi ) bağlı kalmasına yol açan şeydir . IIRC, SQL bölümünde de çok ince hatalar vardı, ancak web sitesini son ziyaret ettiğimden bu yana neredeyse bir yıl geçti ve birçoğu da düzeltilebilir. Ve her şey mükemmel olsa bile, hala sertifikalarının sahtekarlığıyla insanları aldatmaya çalışan bir web sitesini tanıtmayacağım.
Ayakkabı

4
gölgeli sertifikalar bir yana, bu iyi bir referans kaynağıdır ve onları kınamak için dolaşmak SO'nun tüm noktasına karşı üretken.
worc

Yanıtlar:


382

kullanılması setIntervalveyasetTimeout

Sen ilk argüman olarak bir işleve bir başvuru geçirmesi gerektiğini setTimeoutya setInterval. Bu referans şu şekilde olabilir:

  • Anonim bir işlev

    setTimeout(function(){/* Look mah! No name! */},2000);
  • Mevcut bir işlevin adı

    function foo(){...}
    
    setTimeout(foo, 2000);
  • Varolan bir işlevi işaret eden değişken

    var foo = function(){...};
    
    setTimeout(foo, 2000);

    Bir işlevdeki "değişkeni" "işlev adı" ndan ayrı olarak ayarladığımı unutmayın. Değişkenlerin ve işlev adlarının aynı ad alanını işgal ettiği ve birbirini tıkayabildiği açık değildir.

Geçiş argümanları

Bir işlevi çağırmak ve parametreleri iletmek için, zamanlayıcıya atanan geri aramanın içindeki işlevi çağırabilirsiniz:

setTimeout(function(){
  foo(arg1, arg2, ...argN);
}, 1000);

Bağımsız değişkenleri işleyiciye aktarmanın başka bir yöntemi daha vardır, ancak tarayıcılar arası uyumlu değildir .

setTimeout(foo, 2000, arg1, arg2, ...argN);

Geri arama içeriği

Varsayılan olarak, thisyürütüldüğünde geri aramanın bağlamı ( zamanlayıcı tarafından çağrılan işlevin içindeki değeri ) genel nesnedir window. Değiştirmek isterseniz, kullanın bind.

setTimeout(function(){
  this === YOUR_CONTEXT; // true
}.bind(YOUR_CONTEXT), 2000);

Güvenlik

Bu mümkün olsa da, gereken bir dize geçemiyor için setTimeoutya setInterval. Bir dize geçirilmesi yapar setTimeout()veya setInterval()benzer bir işlevi kullanmak eval()olduğunu komut dosyaları gibi yürütür dizeleri keyfi ve potansiyel olarak zararlı betik çalıştırma mümkün hale.


i sadece fonksiyon adını kullanırken fonksiyonun kopyalandığını öğrendim, neden ilk örneğinizde setTumeout foo (fonksiyon) geçme referansının fonksiyonun eğildiğini söylediğinizi söylüyorsunuz. ve bana daha fazla lütfen eval hakkında lütfen.
user1316123

41
@ user1316123 işlevleri asla kopyalanmaz. nesneler ve dizilerle aynı. bunlar olan referans ile bu geçti . w3schools okumayı bırakmalısınız. yarardan çok zarar veriyorlar
Joseph

4
@JosephtheDreamer fonksiyonları olan nesneler. "Bir işlev adı" ve "Bir işleve başvuran bir değişken" aynı şeydir. Ayrıca, setTimeout'a doğrudan parametreler iletebilirsiniz (bunun için bir lambda sarmaya gerek yoktur (söylediğiniz gibi - daha yeni tarayıcılar). diğer kullanıcıların girdilerini kabul ederek ve bunu komut dosyası olarak çalıştırarak , kullanıcının kendileri her zaman konsolu açabilir ve isteğe bağlı JavaScript çalıştırabilir.
Benjamin Gruenbaum

@BenjaminGruenbaum İkinci cümlenize neredeyse aynı bir yorum yapmak üzereydim. Gülmek :)
ErikE

2
SetTimeout'un düzgün çalışması için bir işlev kullanmanız gerektiğini fark etmedim. Temizlediğin için teşekkürler.
Matt Dell

3

yazdığınız setTimeout işlevi çalıştırılmadığını düşünüyorum. jquery kullanıyorsanız, bunu yaparak doğru çalışmasını sağlayabilirsiniz:

    function alertMsg() {
      //your func
    }

    $(document).ready(function() {
       setTimeout(alertMsg,3000); 
       // the function you called by setTimeout must not be a string.
    });

senin gibi Just thinkink ancak bağlantı w3schools.com/js/js_timing.asp diyerek başka somting
user1316123

Eğer köşeli parantez kullanırken doğru anlıyorsam ben sadece setTimeout yöntemini içeren işleve başvurabilir işlevi olabilir çünkü fonksiyon sadece köşeli parantez içinde kullanılabilir?
user1316123

2

Tamamen Joseph ile aynı fikirde.

İşte bunu test etmek için bir keman: http://jsfiddle.net/nicocube/63s2s/

Keman bağlamında, dize argümanı işe yaramaz, bence işlev küresel kapsamda tanımlanmamıştır.


w3schools.com/js/js_timing.asp Eğer link girebilir ve lütfen Joseph tehlikeli olduğunu söylüyor ancak eğer linke
girerseniz

çocuklar lütfen şuna bakın: quirksmode.org/js/this.html Bu bağlantıda bir işlev kopyalanabilir diyor
user1316123

Evet olabilir, çünkü işlev JS'deki nesnedir. Eval ile ilgili sorun, küresel bağlamda değerlendirme yapacak ve bir keman ile oluşan yerel bağlamı elde edememesidir.
Nicocube

eval hakkında bazı kelimeler açıklayabilir misiniz lütfen.
user1316123


1

Dizeyi işlevin ilk parametresi olarak iletmeniz durumunda gerçekte ne olur?

setTimeout ( 'string', number)

çalışma zamanı geldiğinde değerlendirilen ilk parametrenin number(milisaniye geçtikten sonra ) değeridir . Temelde eşittir

setTimeout ( eval('string'), number)

Bu

zamanlayıcı sona erdiğinde derlenen ve yürütülen bir işlev yerine bir dize eklemenizi sağlayan alternatif bir sözdizimi. Bu sözdizimi eval () kullanımını bir güvenlik riski haline getiren aynı nedenlerle önerilmez.

Bu nedenle, referans aldığınız örnekler iyi örnekler değildir ve farklı bağlamlarda veya sadece basit yazım hatalarıyla verilebilir.

Bu şekilde çağırırsanız setTimeout(something, number), ilk parametre dize değil, çağrılan bir şeyin göstergesidir something. Ve yine somethingdize ise - o zaman değerlendirilecektir. Ancak eğer işlev ise, işlev yürütülür. jsbin örneği


0
    ##If i want to wait for some response from server or any action we use setTimeOut.

    functionOne =function(){
    console.info("First");

    setTimeout(()=>{
    console.info("After timeOut 1");
    },5000);
    console.info("only setTimeOut() inside code waiting..");
    }

    functionTwo =function(){
    console.info("second");
    }
    functionOne();
    functionTwo();

## So here console.info("After timeOut 1"); will be executed after time elapsed.
Output:
******************************************************************************* 
First
only setTimeOut() inside code waiting..
second
undefined
After timeOut 1  // executed after time elapsed.

-1

Parantez ile:

setTimeout("alertMsg()", 3000); // It work, here it treat as a function

Tırnak işaretleri ve parantez olmadan:

setTimeout(alertMsg, 3000); // It also work, here it treat as a function

Ve üçüncüsü sadece tırnak işaretleri kullanıyor:

setTimeout("alertMsg", 3000); // It not work, here it treat as a string

function alertMsg1() {
        alert("message 1");
    }
    function alertMsg2() {
        alert("message 2");
    }
    function alertMsg3() {
        alert("message 3");
    }
    function alertMsg4() {
        alert("message 4");
    }

    // this work after 2 second
    setTimeout(alertMsg1, 2000);

    // This work immediately
    setTimeout(alertMsg2(), 4000);

    // this fail
    setTimeout('alertMsg3', 6000);

    // this work after 8second
    setTimeout('alertMsg4()', 8000);

Yukarıdaki örnekte, önce alertMsg2 () işlevini hemen arayın (4S zaman aşımını veriyoruz ama rahatsız etmiyoruz) alertMsg1 () (2 Saniye bekleme süresi) sonra alertMsg4 () (8 Saniye bekleme süresi) ancak alertMsg3 () çalışmıyor, çünkü bunu taraflar olmadan tırnak içine alıyoruz, bu nedenle dize olarak değerlendiriliyor.


Soru soran kişinin sorduğu senaryoları gösterir, ancak aslında soruyu cevaplamaz. Bunun mevcut 6 yaşındaki cevaplara ne kattığını görmüyorum .
Stephen P
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.