2012-12-13 24 views
5

underscore.js library (jQuery aynı şeyi yapıyor) koduna bakıyordum ve sadece pencere nesnesinin kendini yürütme işlevine aktarılmasının nedenini açıklığa kavuşturmak istedim. ÖrneğinDeğişken globalse argümanları javascript'te kendi kendine yürütme işlevine neden aktarmanız gerekiyor?

: this yana

(function() {   //Line 6 
    var root = this;  //Line 12 
    //Bunch of code 
}).call(this);   //Very Bottom 

, neden işleve küresel geçirilmediğini edilir? Aşağıdaki iş de olmaz mıydı? Bu şekilde ne gibi sorunlar ortaya çıkıyor?

(function() { 
    var root = this; 
    //Bunch of code 
}).call(); 
+0

görünüşe göre, aynı yapılır, alt çizgi js kodu gönderebilirsiniz? 'diyoruz callback'inde içindeki this' 'ayarlamak için kullanılıyor' - – jxs

+0

yok argümanlar geçti alıyorsanız. Yine de, bunun neden sadece gönderdiğiniz koddan kaynaklandığını da göremiyorum. – apsillers

+0

fonksiyon Line 6 başlar, değişken kök hattı 12 decalred ve sonra çağrı çok alt kısmında edilir. Bütün dosya büyük bir işlev. 'Var root = penceresinden' olarak yazılmış olabilir;; – KingKongFrog

cevap

4

Nedeni ECMAScript 5 strict mode olduğundan şüpheleniyorum. (Eğer bir node.js sunucuysanız veya global nesneyi) küresel nesne için this olarak verilir, çünkü olmayan katı modda

, Bu hayatı

(function() { 
    console.log(this); // window or global 
})(); 

, window nesneyi kaydeder Bir nesnenin yöntemi olarak çalışmayan işlevler.

Katı modda

"use strict"; 
(function() { 
    console.log(this); // undefined 
})(); 

ile bu sonucu karşılaştırın, bir çıplak çağrılan fonksiyonun this tanımlanmamıştır. Bu nedenle, Altyazı yazarları anonim işlevine açık bir this sağlamak için call kullanın, böylece katı ve katı olmayan modda standardize edilir. Fonksiyonu çağırmak (örneklerimde yaptığım gibi) veya .call() kullanmak, .call(this) ile çözülebilecek bir tutarsızlığa yol açar.

1

jQuery aynı şeyi yapar, ve o doğrultuda arayarak SO üzerinde soruya birkaç cevap bulabilirsiniz.

  1. yükleme süresi:

    oldukça küçük optimizasyonlar uğruna her ikisi de yerel kapsamında window gibi her zaman-hazır küresel değişkeni olması iki nedeni vardır. Yerel bir değişkeni aramak, küresel bir değişkene bakmaktan çok daha az zaman alır, çünkü tercüman bağlam ağacına kadar uzak görünmek zorunda değildir. Bir fonksiyonun uzunluğu boyunca, daha yavaş makinelerde teorik olarak daha az önemsiz bir süre ekleyebilen, Underscore veya jQuery'nin boyutu boyunca.

  2. Dosya boyutu. Javascript küçültme, değişkenlerin tutarlı oldukları sürece herhangi bir şekilde adlandırılabileceği gerçeğine dayanır. myLongVariableName, küçültülmüş sürümde a olur. Yakalama elbette, bu sadece betik içinde tanımlanan değişkenlere uygulanabilir; Dışarıdan çektiği her şey, aynı adı çalışmaya devam ettirmek zorundadır, çünkü window'u pr'a indirirseniz, tercüman ne hakkında konuştuğunuzu bilmeyecektir. kendisine referans ile gölgeleme ederek, küçültme gibi şeyler yapabiliriz: Eğer aksi window (6 karakter) koymak olurdu

    (function(A){ B(A, {...}); A.doStuff(); //etc });})(window) 
    

    ve her zaman artık A (1 karakter) var. Yine, büyük değil, ancak kapsam yönetimi için düzenli olarak window'u çağırması gereken büyük bir dosyada bu önemli olabilir ve iki kez kullanıyorsanız birkaç karakter tarafından zaten bir avantaj elde ettiniz. Ve sınırlı sunucuların ve kötücül internet planlarına sahip olabilecek insanlara sunulan geniş ve popüler kütüphanelerde her bayt sayılır.


Düzen soru üzerine yorumları okuduktan sonra: Eğer what function.call() actually does bakarsanız, ikinci pasajı aslında işe yaramaz

- this içinde geçirilen bir açık var, bir argüman değil işlevi için bağlamı çağırıyor ve bunu .call()'a bildirmeniz gerekiyor. Dosyanın başında bulunan satır, yukarıdaki iki amaca hizmet eder. Bağlamı call ile açıkça belirleme sebebi şu anda geçerli değil - anonim işlevler genel bağlamı sağlıyor, ancak teorik olarak değişebilecek, gelecekteki bir ECMA belirtiminde cesaret kırılmayacak ya da tek bir tarayıcıda garip davranabiliyor. İnternetin yarısının kullandığı bir şey için, daha açık olmak ve sorunu tamamen ortadan kaldırmak en iyisidir. En üst düzeydeki this/window seçiminin, üst düzey nesneler için farklı bir ad kullanarak potansiyel olarak PC olmayan aygıtlar (yani mobil) hakkında endişelenmekle ilgili bir şeyleri olması gerekir.