wake-up-neo.com

Warum eine anonyme Funktion definieren und als Argument jQuery übergeben?

Ich schaue mir den exzellenten Peepcode-Demo-Code aus den Screencasts von backbone.js an. Der Backbone-Code ist in einer anonymen Funktion eingeschlossen, die das jQuery-Objekt übergibt:

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

In meinem eigenen Backbone-Code habe ich gerade meinen gesamten Code in das Ereignis jQuery DOM 'ready' eingebunden:

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

Was ist der Punkt/Vorteil des ersten Ansatzes? Auf diese Weise wird eine anonyme Funktion erstellt, die sofort ausgeführt wird, wobei das jQuery-Objekt als Funktionsargument übergeben wird. So wird sichergestellt, dass $ das jQuery-Objekt ist. Ist dies der einzige Punkt - um zu garantieren, dass jQuery an '$' gebunden ist, oder gibt es andere Gründe dafür?

86
Matt Roberts

Die beiden von Ihnen gezeigten Codeblöcke unterscheiden sich drastisch, wann und warum sie ausgeführt werden. Sie schließen sich nicht aus. Sie dienen nicht demselben Zweck.

JavaScript-Module


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

Dies ist ein "JavaScript-Modul" -Muster, das mit einer sofort aufrufenden Funktion implementiert wird.

Der Zweck dieses Codes ist die Bereitstellung von "Modularität", Datenschutz und Einkapselung für Ihren Code. 

Die Implementierung dieser Funktion ist eine Funktion, die sofort von der aufrufenden (jQuery)-Klammer aufgerufen wird. Der Zweck der Übergabe von jQuery an die Klammer besteht darin, die globale Variable mit einem lokalen Gültigkeitsbereich zu versehen. Dies verringert den Aufwand für das Nachschlagen der $-Variablen und ermöglicht in manchen Fällen eine bessere Komprimierung/Optimierung für Minifier.

Funktionen, die sofort aufgerufen werden, werden sofort ausgeführt. Sobald die Funktionsdefinition abgeschlossen ist, wird die Funktion ausgeführt. 

die Funktion "DOMReady" von jQuery

Dies ist ein Alias ​​für die "DOMReady" -Funktion von jQuery: http://api.jquery.com/ready/


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

die "DOMReady" -Funktion von jQuery wird ausgeführt, wenn das DOM von Ihrem JavaScript-Code bearbeitet werden kann.

Module im Vergleich zu DOMReady In Backbone Code

Es ist nicht geeignet, Ihren Backbone-Code in der DOMReady-Funktion von jQuery zu definieren und die Anwendungsleistung möglicherweise zu beeinträchtigen. Diese Funktion wird erst aufgerufen, wenn das DOM geladen wurde und zur Bearbeitung bereit ist. Das heißt, Sie warten, bis der Browser das DOM mindestens einmal analysiert hat, bevor Sie Ihre Objekte definieren. 

Es ist eine bessere Idee, Ihre Backbone-Objekte außerhalb einer DOMReady-Funktion zu definieren. Ich ziehe es unter vielen anderen vor, dies innerhalb eines JavaScript-Modul-Musters zu tun, damit ich meinen Code mit Kapselung und Datenschutz versehen kann. Ich neige dazu, das "Revealing Module" -Muster (siehe den ersten Link oben) zu verwenden, um Zugriff auf die Bits zu erhalten, die ich außerhalb meines Moduls benötige.

Durch die Definition Ihrer Objekte außerhalb der DOMReady-Funktion und die Möglichkeit, auf sie zu verweisen, geben Sie dem Browser die Möglichkeit, sich mit der Verarbeitung von JavaScript zu beschäftigen, was die Benutzererfahrung möglicherweise beschleunigt. Außerdem wird der Code flexibler, da Sie Dinge verschieben können, ohne sich um das Erstellen weiterer DOMREady-Funktionen kümmern zu müssen, wenn Sie Dinge verschieben.

Sie werden wahrscheinlich eine DOMReady-Funktion verwenden, selbst wenn Sie Ihre Backbone-Objekte an anderer Stelle definieren. Der Grund ist, dass viele Backbone-Apps das DOM auf irgendeine Weise manipulieren müssen. Dazu müssen Sie warten, bis das DOM bereit ist. Daher müssen Sie die DOMReady-Funktion verwenden, um Ihre Anwendung zu starten, nachdem sie definiert wurde.

Es gibt viele Beispiele dafür im Web, aber hier ist eine sehr grundlegende Implementierung, die sowohl ein Modul als auch die DOMReady-Funktion verwendet:



// 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

Als Nebenbemerkung bewirkt das Senden von $ als Argument an eine anonyme Funktion, dass $ local für diese Funktion gemacht wird. Dies hat eine kleine positive Auswirkung auf die Leistung, wenn die $ - Funktion viel aufgerufen wird. Dies liegt daran, dass Javascript zunächst den lokalen Gültigkeitsbereich nach Variablen durchsucht und dann den gesamten Gültigkeitsbereich des Fensters durchläuft (in dem $ normalerweise lebt).

13
joidegn

Es stellt sicher, dass Sie always$ innerhalb dieses Verschlusses verwenden können, auch wenn $.noConflict() verwendet wurde.

Ohne diese Schließung würden Sie jQuery anstelle von $ die ganze Zeit verwenden.

9
ThiefMaster

Dies dient dazu, einen möglichen Konflikt der $ -Variable zu vermeiden. Wenn eine Variable mit dem Namen $ definiert wird, verwendet Ihr Plugin möglicherweise die falsche Definition

Weitere Informationen hierzu finden Sie unter http://docs.jquery.com/Plugins/Authoring#Getting_Started

4
Andrew Brock

Verwende beide.

Die selbstaufrufende Funktion, mit der Sie in jQuery übergeben, um Bibliothekskonflikte zu vermeiden und lediglich sicherzustellen, dass jQuery so verfügbar ist, wie Sie es von $ erwarten würden. 

Und die .ready () - Verknüpfungsmethode, die erforderlich ist, um Javascript erst auszuführen, nachdem DOM geladen wurde:

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

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