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, bar
tü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 foo
edilir 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ı foo
kaldırılır, görev "orijinal" (kaldırılmamış) kodda göründüğü yere gelir. Çağrıldığında bar
, daha önce foo
bir değer atanır, yani foo === undefined
. Şimdi işlev gövdesinde, bar
yapıyormuşsunuz gibi undefined()
, bu da bir hata verir.