web-dev-qa-db-fra.com

Pourquoi définir une fonction anonyme et lui passer comme argument jQuery?

Je suis à la recherche de l'excellent code de démonstration Peepcode des screencasts de backbone.js. Dans celui-ci, le code du backbone est contenu dans une fonction anonyme à laquelle est transmis l'objet jQuery:

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

Dans mon propre code de colonne vertébrale, je viens juste d'envelopper tout mon code dans l'événement "prêt" de jQuery DOM:

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

Quel est le point/avantage de la première approche? Le faire de cette manière crée une fonction anonyme qui est ensuite exécutée immédiatement avec l'objet jQuery transmis en tant qu'argument de fonction, garantissant ainsi que $ est l'objet jQuery. Est-ce le seul objectif - garantir que jQuery est lié à '$' ou existe-t-il d'autres raisons de le faire?

86
Matt Roberts

Les deux blocs de code que vous avez présentés diffèrent considérablement du moment et de la raison de leur exécution. Ils ne sont pas exclusifs les uns des autres. Ils ne servent pas le même but.

Modules JavaScript


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

Il s'agit d'un modèle "Module JavaScript", implémenté avec une fonction appelant immédiatement.

Le but de ce code est de fournir "la modularité", la confidentialité et l’encapsulation de votre code. 

L'implémentation de this est une fonction qui est immédiatement appelée par la parenthèse appelante (jQuery). Le passage de jQuery à la parenthèse a pour but de fournir une portée locale à la variable globale. Cela permet de réduire les frais généraux liés à la recherche de la variable $ et permet une meilleure compression/optimisation pour les minificateurs dans certains cas.

Les fonctions appelant immédiatement sont exécutées, eh bien, immédiatement. Dès que la définition de la fonction est terminée, la fonction est exécutée. 

fonction "DOMReady" de jQuery

C'est un alias de la fonction "DOMReady" de jQuery: http://api.jquery.com/ready/


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

la fonction "DOMReady" de jQuery s'exécute lorsque le DOM est prêt à être manipulé par votre code JavaScript.

Modules vs DOMReady In Backbone Code

C'est une mauvaise forme de définir votre code Backbone à l'intérieur de la fonction DOMReady de jQuery, et potentiellement préjudiciable aux performances de votre application. Cette fonction n'est appelée que lorsque le DOM est chargé et prête à être manipulée. Cela signifie que vous attendez que le navigateur ait analysé le DOM au moins une fois avant de définir vos objets. 

C'est une meilleure idée de définir vos objets Backbone en dehors d'une fonction DOMReady. Je préfère, parmi beaucoup d'autres, faire cela à l'intérieur d'un modèle de module JavaScript afin de pouvoir fournir une encapsulation et une confidentialité pour mon code. J'ai tendance à utiliser le modèle "Révéler le module" (voir le premier lien ci-dessus) pour fournir l'accès aux bits dont j'ai besoin en dehors de mon module.

En définissant vos objets en dehors de la fonction DOMReady et en fournissant un moyen de les référencer, vous permettez au navigateur de prendre une longueur d'avance sur le traitement de votre JavaScript, accélérant ainsi potentiellement l'expérience de l'utilisateur. Cela rend également le code plus flexible car vous pouvez déplacer des éléments sans avoir à vous soucier de créer davantage de fonctions DOMREady lorsque vous déplacez des éléments.

Vous allez probablement utiliser une fonction DOMReady, même si vous définissez vos objets Backbone ailleurs. La raison en est que beaucoup d'applications Backbone ont besoin de manipuler le DOM d'une manière ou d'une autre. Pour ce faire, vous devez attendre que le DOM soit prêt. Par conséquent, vous devez utiliser la fonction DOMReady pour démarrer votre application une fois celle-ci définie.

Vous pouvez trouver de nombreux exemples sur le Web, mais voici une implémentation très basique, utilisant à la fois un module et la fonction DOMReady:



// 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();
});
166
Derick Bailey

En tant que note mineure, envoyer $ comme argument d'une fonction anonyme rend $ local à cette fonction, ce qui a une petite implication positive sur les performances si la fonction $ est appelée beaucoup En effet, javascript cherche d’abord les variables dans la portée locale, puis s’étend jusqu’à la portée de la fenêtre (où habite habituellement $).

13
joidegn

Cela vous permet de toujours utiliser $ dans cette fermeture, même si $.noConflict() a été utilisé.

Sans cette fermeture, vous seriez supposé utiliser jQuery au lieu de $ tout le temps.

9
ThiefMaster

C'est pour éviter un conflit potentiel de la variable $ . Si quelque chose d'autre définit une variable nommée $, votre plugin peut utiliser une mauvaise définition.

Reportez-vous à http://docs.jquery.com/Plugins/Authoring#Getting_Started pour plus de détails.

4
Andrew Brock

Utilise les deux.

Fonction d'invocation automatique dans laquelle vous passez dans jQuery pour éviter les conflits de bibliothèque et pour vous assurer que jQuery est disponible comme vous le souhaiteriez avec $. 

Et la méthode de raccourci .ready () nécessaire pour exécuter javascript après le chargement de DOM:

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

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