Neden anonim bir işlevi tanımlayıp argüman olarak jQuery'yi iletelim?


100

Backbone.js ekran video kayıtlarından mükemmel gözetleme kodu demo koduna bakıyorum. İçinde, omurga kodunun tamamı jQuery nesnesini ileten anonim bir işlevin içindedir:

(function($) {
  // Backbone code in here
})(jQuery);

Kendi omurga kodumda, tüm kodumu jQuery DOM 'ready' olayına sardım:

$(function(){
  // Backbone code in here
});

İlk yaklaşımın amacı / avantajı nedir? Bunu bu şekilde yapmak, anonim bir işlev oluşturur ve ardından jQuery nesnesi işlev bağımsız değişkeni olarak iletilirken, $ 'ın jQuery nesnesi olmasını etkin bir şekilde sağlar. JQuery'nin "$" a bağlı olduğunu garanti etmek için tek nokta bu mu yoksa bunu yapmanın başka nedenleri var mı?


4
Bunun yerine önce SO'ya göz atmalıydın.
Alexander

Diğer kitaplıklarla birlikte çalışabilirlik - sayfa yazarının kullanması gerekiyorsa $.noConflict(), ilk örnek yine de çalışacaktır.
DCoder

Olası yineleme: jQuery ve $ sorular
Alexander

Olası yinelenen jQuery document.ready ile kendi kendini çağıran anonim işlevi arasındaki farkı görün
Bergi

@Alexander ama sonra diğer insanlar bu soruyu önce SO'da bulacaklar. :-)
caiosm1005

Yanıtlar:


184

Gösterdiğiniz iki kod bloğu, ne zaman ve neden yürütüldükleri açısından önemli ölçüde farklıdır. Birbirlerini dışlamazlar. Aynı amaca hizmet etmiyorlar.

JavaScript Modülleri


(function($) {
  // Backbone code in here
})(jQuery);

Bu, hemen çağıran bir işlevle uygulanan bir "JavaScript Modülü" modelidir.

Bu kodun amacı, kodunuz için "modülerlik", gizlilik ve kapsülleme sağlamaktır.

Bunun uygulanması, çağıran (jQuery)parantez tarafından hemen çağrılan bir işlevdir . JQuery'yi paranteze geçirmenin amacı, global değişkene yerel kapsam sağlamaktır. Bu, $değişkene bakmanın ek yükünü azaltmaya yardımcı olur ve bazı durumlarda küçültme araçları için daha iyi sıkıştırma / optimizasyon sağlar.

Anında çağrılan işlevler hemen çalıştırılır. Fonksiyon tanımı tamamlanır tamamlanmaz, fonksiyon yürütülür.

jQuery'nin "DOMReady" işlevi

Bu, jQuery'nin "DOMReady" işlevinin takma adıdır: http://api.jquery.com/ready/


$(function(){
  // Backbone code in here
});

jQuery'nin "DOMReady" işlevi, DOM JavaScript kodunuz tarafından değiştirilmeye hazır olduğunda çalıştırılır.

Modüller vs DOMReady In Backbone Code

Omurga kodunuzu jQuery'nin DOMReady işlevi içinde tanımlamak kötü bir biçimdir ve uygulama performansınıza potansiyel olarak zarar verir. Bu işlev, DOM yüklenene ve değiştirilmeye hazır olana kadar çağrılmaz. Bu, nesnelerinizi tanımlamadan önce tarayıcının DOM'u en az bir kez ayrıştırmasını beklediğiniz anlamına gelir.

Backbone nesnelerinizi DOMReady işlevi dışında tanımlamak daha iyi bir fikirdir. Diğerlerinin yanı sıra, bunu bir JavaScript Modülü modeli içinde yapmayı tercih ediyorum, böylece kodum için kapsülleme ve gizlilik sağlayabiliyorum. Modülümün dışında ihtiyacım olan bitlere erişim sağlamak için "Gösterme Modülü" modelini (yukarıdaki ilk bağlantıya bakın) kullanma eğilimindeyim.

Nesnelerinizi DOMReady işlevinin dışında tanımlayarak ve onlara başvurmak için bir yol sunarak, tarayıcının JavaScript'inizi işlemeye bir adım atmasına izin vererek potansiyel olarak kullanıcı deneyimini hızlandırmış olursunuz. Ayrıca, bir şeyleri hareket ettirdiğinizde daha fazla DOMREady işlevi oluşturma konusunda endişelenmenize gerek kalmadan nesneleri hareket ettirebileceğiniz için kodu daha esnek hale getirir.

Backbone nesnelerinizi başka bir yerde tanımlasanız bile muhtemelen DOMReady işlevini kullanacaksınız. Bunun nedeni, birçok Backbone uygulamasının DOM'u bir şekilde değiştirmesi gerektiğidir. Bunu yapmak için DOM hazır olana kadar beklemeniz gerekir, bu nedenle uygulamanızı tanımlandıktan sonra başlatmak için DOMReady işlevini kullanmanız gerekir.

Web'de bununla ilgili birçok örnek bulabilirsiniz, ancak burada hem Modül hem de DOMReady işlevini kullanan çok temel bir uygulama:



// Define "MyApp" as a revealing module

MyApp = (function(Backbone, $){

  var View = Backbone.View.extend({
    // do stuff here  
  });

  return {
    init: function(){
      var view = new View();
      $("#some-div").html(view.render().el);
    }
  };

})(Backbone, jQuery);



// Run "MyApp" in DOMReady

$(function(){
  MyApp.init();
});

1
Bu ayrıntılı yanıt için teşekkürler. DOMReady işlevinin yalnızca DOM ready olayı tetiklendiğinde çağrıldığını biliyordum, ancak bunun bir sorun olacağını hiç düşünmemiştim. Kodu bir modülün içindeki omurga bitlerini tanımlamaya bölmek ve ardından onlarla dom ready'de etkileşim kurmak gerçekten de en iyi yaklaşım gibi görünüyor
Matt Roberts

2
İlginç bir şekilde, omurga src ile "yapılacak işler" örnek uygulaması doma her şeyi hazır hale getirir.
Matt Roberts

2
Unutmayın, javascript modülü kalıbı aynı zamanda IIFE.
Jess

1
anonim işlev esasen DOM'a hazır olarak aynı anda çalıştırılır, bu yüzden onları nasıl daha verimli kılar?
bhavya_w

14

Küçük bir yan not olarak, anonim bir işleve argüman olarak $ göndermek, $ işlevi çok çağrılırsa küçük bir pozitif performans sonucuna sahip olan $ yerel yapar. Bunun nedeni, javascript'in önce değişkenler için yerel kapsamı araması ve ardından pencere kapsamına ($ genellikle burada yaşadığı) kadar aşağıya inmesidir.


9

Kullanılmış olsa bile her zaman$ bu kapağın içinde kullanabilmenizi sağlar $.noConflict().

Bu kapanış olmadan tüm zaman jQueryyerine kullanmanız gerekir $.



2

İkisini de kullan.

Kitaplık çakışmalarını önlemek ve sadece jQuery'nin $ ile beklediğiniz gibi kullanılabilir olduğundan emin olmak için jQuery'de ilettiğiniz kendi kendini çağıran işlev.

Ve javascript'i yalnızca DOM yüklendikten sonra çalıştırmak için gereken .ready () kısayol yöntemi:

(function($) {
    $(function(){
          //add code here that needs to wait for page to be loaded
    });

    //and rest of code here
})(jQuery);

jQuery(function ($, undefined) { /* Code */ });
SO'da
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.