2013-02-13 21 views
7

Ben Chrome Geliştirici Araçları içinde bu kodu çalıştırırsanız:Hata ayıklama Modülü Gösterme Deseni: işlevler çağrılana kadar kapsam dışıdır?

var test = (function() { 

    var publicFunction, 
     privateFunction1, 
     privateFunction2; 

    privateFunction1 = function privateFunction1() { 
    return true; 
    }; 

    privateFunction2 = function privateFunction2() { 
    return true; 
    }; 

    publicFunction = function publicFunction() { 
    privateFunction1(); 
    debugger; 
    }; 

    return { 
    publicFunction: publicFunction 
    }; 
})(); 

neden privateFunction2 değilken, kesme noktasında kapsamında privateFunction1 mı?

Screenshot of Chrome Dev Tools

+1

Yan not: Bildirdiğiniz değişkenler tarafından sunulan hiçbir amaç yoktur, bunun yerine bunu yapabilirsiniz (ve muhtemelen): http://pastie.org/6150861 IE8 ve altındaki bu değişkenler, fonksiyonlarınızın her biri için iki işlev oluşturuyorsunuz (iki farklı zamanda). Bir olay işleyicisini, ikisinden birini kullanarak koparmadıkça ve diğeriyle daha sonra çıkarmaya çalışmadığınız sürece, hiçbir fark yaratmayan bir fark. Blogumda daha fazlası: [* Double-take *] (http://blog.niftysnippets.org/2010/09/double-take.html) –

+1

Eh, düşündüm * çünkü V8 (Chrome'un JavaScript motoru) 'privateFunction2' öğesini tamamen kaldırmak için herhangi bir yerde kullanılmadığından (ölü koddu). Sonra onu başka bir yerde kullanarak kanıtlamaya çalıştım ve bu hiçbir şeyi değiştirmedi. Çok tuhaf. –

+0

Teşekkürler, NF'ler ile IE sorunları hakkında bilmiyordum. Yine de, kaldırma işleminden hoşlanmamamdan dolayı, beyanlar üzerinde isimlendirilmiş işlev ifadelerini tercih ederim. – janfoeh

cevap

4

Büyüleyici bir soru.

privateFunction2publicFunction için kapsam olmakla publicFunction aslında hiç kullanmaz. Hata ayıklayıcısında gördüğünüzün, V8'in (Chrome'un JavaScript motoru) çeşitli nedenlerle (bellek kullanımını en aza indirgeme dahil) kapakların içeriğini optimize etmesi nedeniyle olduğuna inanıyorum. Teoride, spesifikasyona göre, publicFunction, tanımlandığı şekilde kapsamdaki tüm sembolleri kaplamaktadır (kalıcı bir referansa sahiptir). Özellikle, en dış anonim işlevinize yapılan çağrı için bir execution context oluşturuldu ve bu yürütme bağlamı,ile ilişkili bir lexical environment içeriyor ve publicFunction, örtülü, anonim bir referansa sahip. Bu bağlanma nesnesinin üzerinde (teoride) publicFunction, privateFunction1, privateFunction2 ve diğer birkaç şey (arguments ve benzeri) üzerinde özellikleri vardır.

Ama olay publicFunction aslında privateFunction1 ama referans şey olmamasıdır, ve bunun için yerinde koduyla, bu başka değil referans şey olabilir. Başka bir şeye atıfta bulunmak için kodunu değiştirmelisiniz ve elbette V8 farklı bir karar verecekti. publicFunction'daki kodun eval(string) veya new Function(string) çağrıları yoktur, dolayısıyla V8 referans aldığı semboller üzerinde statik bir analiz yapmakta serbesttir. Bu, hata ayıklayıcısını içermeyen, bu diğer özellikleri koruyan bağlayıcı nesneye ne olursa olsun bir nokta olmadığı anlamına gelir. Hiç kullanılmazlar.

V8 agresif olarak optimize eden bir derleyici olduğundan (evet, derleyici), görünüşe göre, yürütme içeriğinin bağlama nesnesindeki ölü özellikleri kaldırır.

Bir şey için privateFunction2 kullanan publicFunction'a bir şey eklerseniz, privateFunction1 yapabildiğim gibi konsoldan buna başvurabilirim.

+0

Doğru gibi gözüküyorsunuz: publicFunction'a bir parametre verir ve değerlendirirseniz, her şey kapsamda beklendiği gibi görünür. Teşekkür ederim! – janfoeh

+0

@janfoeh: Bu yardımcı oldu sevindim! –

İlgili konular