tl; dr Her şey yüklenene kadar hiçbir şey aramıyorsanız, iyi olmalısınız.
Düzenleme: Bazı ES6 bildirimlerini de kapsayan bir genel bakış için ( let, const): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Scope_Cheatsheet
Bu garip davranış şunlara bağlıdır:
- İşlevleri nasıl tanımlarsınız ve
- Onları aradığınızda.
İşte bazı örnekler.
bar(); //This won't throw an error
function bar() {}
foo(); //This will throw an error
var foo = function() {}
bar();
function bar() {
foo(); //This will throw an error
}
var foo = function() {}
bar();
function bar() {
foo(); //This _won't_ throw an error
}
function foo() {}
function bar() {
foo(); //no error
}
var foo = function() {}
bar();
Bunun nedeni, kaldırma denen bir şeydir !
İşlevleri tanımlamanın iki yolu vardır: İşlev bildirimi ve işlev ifadesi . Aradaki fark can sıkıcı ve çok küçük, bu yüzden biraz yanlış bir şey söyleyelim: Eğer böyle yazıyorsanız function name() {}, bu bir bildiridir ve bunu şöyle yazdığınızda var name = function() {}(veya bir dönüşe atanmış anonim bir işlev, bunun gibi şeyler), bir işlev ifadesi .
İlk olarak, değişkenlerin nasıl ele alındığına bakalım:
var foo = 42;
//the interpreter turns it into this:
var foo;
foo = 42;
Şimdi, işlev bildirimleri nasıl işlenir:
var foo = 42;
function bar() {}
//turns into
var foo; //Insanity! It's now at the top
function bar() {}
foo = 42;
varİfadeleri "atar" oluşturulmasını ait fooçok üstüne, ancak henüz buna değer atamaz. İşlev bildirimi sırada gelir ve son olarak bir değer atanır foo.
Peki ya bu?
bar();
var foo = 42;
function bar() {}
//=>
var foo;
function bar() {}
bar();
foo = 42;
Sadece beyan ait fooüstüne taşınır. Atama, yalnızca arama yapıldıktan sonra, bartüm kaldırma gerçekleşmeden önce olduğu yerde gelir.
Ve son olarak, özlülük için:
bar();
function bar() {}
//turns to
function bar() {}
bar();
Şimdi, fonksiyon ifadeleri ne olacak ?
var foo = function() {}
foo();
//=>
var foo;
foo = function() {}
foo();
Sadece düzenli değişkenler gibi, ilk fooedilir ilan o zaman bir değer atanır, kapsamı en yüksek noktasında.
İkinci örneğin neden bir hata verdiğini görelim.
bar();
function bar() {
foo();
}
var foo = function() {}
//=>
var foo;
function bar() {
foo();
}
bar();
foo = function() {}
Daha önce gördüğümüz gibi, sadece oluşturulması fookaldırılır, görev "orijinal" (kaldırılmamış) kodda göründüğü yere gelir. Çağrıldığında bar, daha önce foobir değer atanır, yani foo === undefined. Şimdi işlev gövdesinde, baryapıyormuşsunuz gibi undefined(), bu da bir hata verir.