21

JavaScript'te dinamik olarak oluşturulmuş bir "a" etiketinin onclick olayına bir işlev atamaya çalışıyorum.Bir döngüdeki (başka bir işlevi döndüren) işlev nasıl çalışır?

for (var i = 0; i < 4; i++) 
{ 
    var a = document.createElement("a"); 
    a.onclick = function() { alert(i) }; 
    document.getElementById("foo").appendChild(a); 
} 

dört bağlantılar için uyarı değeri her zaman "4" dir: şöyle etiketlerin tamamı bir döngü oluşturulur. Gayet açık. Googling zaman aşağıdaki kod parçacığını gösteren bir yazı geldi:

a.onclick = (function(p, d) { 
return function(){ show_photo(p, d) } 
})(path, description); 

benim ihtiyaçları için çimdik başardı ve uyarı (i) şey düzgün çalışması için var ama birisi tam olarak açıklayabilir misin diye takdir edersiniz Yukarıdaki kod ne yapar.

+0

Hi:

Ben kapanışları (ve curry bir çok temel kavram) açıklamak için aşağıdaki parçacığını kullanın, ben basit bir örnek kavramını almak için daha kolay hale getirebilir düşünüyorum Uyarılar "4"? "2" olmasın mı? Teşekkürler. – Tarik

+0

için (var i = 0; i <3; i ++) i == 4 sonunda –

+1

Hayır, 3 olarak kalıyor. –

cevap

45

: Sorununuz bir işlev dönen bir işlev kullanmaktır.

Temel olarak, işlevleri yerleştirdiğinizde bir kapatma oluşur; iç işlevler, üst işlevleri zaten yürütüldükten sonra bile dış çevreleme işlevlerinde bulunan değişkenlere başvurabilir.

Tıklatma olayının yürütüldüğü anda, işleyici, i değişkeninin sahip olduğu son değere başvurur, çünkü bu değişken kapağın üzerinde saklanır.Fark gibi

, başka bir fonksiyon argüman olarak i değişken kabul etmek için tıklayın eylemcisini sarma ve dönerek o beklediğiniz gibi çalışır (temelde başka kapatma oluşturmak):

for (var i = 0; i < 4; i++) { 
    var a = document.createElement("a"); 
    a.onclick = (function(j) { // a closure is created 
    return function() { 
     alert(j); 
    } 
    }(i)); 
    document.getElementById("foo").appendChild(a); 
} 

seni yineleyin, aslında 4 fonksiyon yaratın, her bir fonksiyon i (i geçerek) oluşturulduğu anda bir referansı saklar, bu değer dış kapanda saklanır ve tıklama olayı patladığında iç işlev yürütülür. neden söyler misiniz,

// a function that generates functions to add two numbers 
function addGenerator (x) { // closure that stores the first number 
    return function (y){ // make the addition 
    return x + y; 
    }; 
} 

var plusOne = addGenerator(1), // create two number adding functions 
    addFive = addGenerator(5); 

alert(addFive(10)); // 15 
alert(plusOne(10)); // 11 
+3

Taylor, Senin için mutluyum, bitirmene izin vereceğim, ama bu yazı tüm zamanların en iyisi. – Tarik

+0

Hiç şaşkınlık yok 42k puan :) –

+4

Bir gün, insanlar benim gibi Kanye West'i unutmuş olacaklar, ve ona atıfta bulunan tüm memeler sadece kaba ve biraz garip gelecektir. – RandomInsano

10

Çok fazla ayrıntıya girmeden, bu, örnek değişkenlerin kopyalarını hemen yürütecek ve öğeyi tıklatıldığında çalıştırılacak işleve geri geçirecek bir işlev içinde paketleyerek kopyalar oluşturur. Böyle bunun

Think:

function() { alert(i); } // Will expose the latest value of i 
(function(I) { return function() { alert(I); }; })(i); // Will pass the current 
                 // value of i and return 
                 // a function that exposes 
                 // i at that time 

Yani her döngü tekrarında sırasında aslında yürütme değişkenin akım değere sahip bir fonksiyonunu döndüren bir fonksiyon vardır.

, sen olarak görülebilir 4 ayrı işlevleri yaratıyor senin döngü içinde 4 çapa olduğunu düşünün eğer ..

function() { alert(0); }; 
function() { alert(1); }; 
function() { alert(2); }; 
function() { alert(3); }; 

Ben javascript ile kapsamı ve kapanışları bakarak düşünün olsaydı gibi Bu yoldan aşağı inin ve ne olduğunu tam olarak anlamayın, beklenmedik davranışlardan büyük problemlere dönüşebilirsiniz.

Onclick olay tetiklendiğinde, anonim fonksiyonu olarak adlandırılır ve bu döngüde kullanılan aynı değişken i belirtmektedir ve bu 4.

çözüm, i son değer tutar

+0

Açıklama için teşekkürler. Bu güzel bir korsanlık mı? Ya da javascript’te yapılma şekli mi? – Amarghosh

2

bir closure oluşturulur, tıklama işleyicisi işlevi atadığınızda

a.onclick = (function(k) {return function() { alert(k); }; })(i); 
İlgili konular