¿Por qué definir una función anónima y pasarla jQuery como argumento?


Estoy mirando a través del excelente código de demostración de peepcode desde la columna vertebral.js screencasts. En él, el código de red troncal está todo encerrado en una función anónima a la que se le pasa el objeto jQuery:

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

En mi propio código troncal, acabo de empaquetar todo mi código en el evento 'ready' de jQuery DOM:

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

¿Cuál es el punto/ventaja del primer enfoque? Hacerlo de esta manera crea una función anónima que luego se ejecuta inmediatamente con el objeto jQuery que se pasa como el argumento de función, asegurando efectivamente que $ es el objeto jQuery. ¿Es este el único punto - para garantizar que jQuery está obligado a ' $ ' o hay otras razones para hacer esto?

Author: ivarni, 2012-04-29

5 answers

Los dos bloques de código que ha mostrado son dramáticamente diferentes en cuándo y por qué se ejecutan. No son exclusivos el uno del otro. No sirven para el mismo propósito.

Módulos JavaScript


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

Este es un patrón de "Módulo JavaScript", implementado con una invocación inmediata función.

El propósito de este código es proporcionar "modularidad", privacidad y encapsulación para su código.

La implementación de esta es una función que es invocada inmediatamente por el paréntesis invocador (jQuery). El propósito de pasar jQuery a la el paréntesis es para proporcionar un alcance local a la variable global. Esto ayuda a reducir la cantidad de sobrecarga de buscar la variable $, y permite una mejor compresión / optimización para los minificadores en algunos casos.

Las funciones que invocan inmediatamente se ejecutan, bueno, inmediatamente. Tan pronto como se completa la definición de la función, se ejecuta la función.

La función "domReady" de jQuery

Este es un alias de la función "domReady" de jQuery: http://api.jquery.com/ready /


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

La función "domReady" de jQuery se ejecuta cuando el DOM está listo para ser manipulado por su código JavaScript.

Módulos vs domReady En Código Troncal

Es una mala forma definir su código troncal dentro de la función domReady de jQuery, y potencialmente perjudicial para el rendimiento de su aplicación. Esta función no se llama hasta que el DOM se ha cargado y está listo para ser manipulado. Eso significa que está esperando hasta que el navegador tenga analizó el DOM al menos una vez antes de definir sus objetos.

Es mejor definir tus objetos Backbone fuera de una función domReady. Yo, entre muchos otros, prefiero hacer esto dentro de un patrón de módulo JavaScript para que pueda proporcionar encapsulación y privacidad para mi código. Tiendo a usar el patrón de "Módulo Revelador" (ver el primer enlace anterior) para proporcionar acceso a los bits que necesito fuera de mi módulo.

Definiendo sus objetos fuera del domReady función, y proporcionar alguna manera de hacer referencia a ellos, que está permitiendo que el navegador para obtener una ventaja en el procesamiento de su JavaScript, potencialmente acelerar la experiencia del usuario. También hace que el código sea más flexible, ya que puede mover cosas sin tener que preocuparse por crear más funciones domReady cuando mueve cosas.

Es probable que vaya a usar una función domReady, aún así, incluso si define sus objetos Backbone en otro lugar. La razón es que muchas aplicaciones troncales necesitan para manipular el DOM de alguna manera. Para hacer esto, debe esperar hasta que el DOM esté listo, por lo tanto, debe usar la función domReady para iniciar su aplicación después de que se haya definido.

Puedes encontrar muchos ejemplos de esto en la web, pero aquí tienes una implementación muy básica, usando tanto un Módulo como la función 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();
});
 162
Author: Derick Bailey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-29 13:20:20

Como una nota secundaria menor, enviar $ como argumento a una función anónima hace local local a esa función que tiene una pequeña implicación de rendimiento positivo si la función $ se llama mucho. Esto se debe a que javascript busca las variables en el ámbito local primero y luego recorre todo el camino hasta el ámbito de la ventana (donde lives generalmente vive).

 13
Author: joidegn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-23 14:34:46

Se asegura de que pueda siempre usar $ dentro de ese cierre, incluso si $.noConflict() fue usado.

Sin este cierre, se supone que debes usar jQuery en lugar de $ todo el tiempo.

 9
Author: ThiefMaster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-29 10:56:43

Es para evitar un conflicto potencial de la variable$. Si algo más define una variable llamada $, su plugin puede usar la definición incorrecta

Refiérase a http://docs.jquery.com/Plugins/Authoring#Getting_Started para más detalles

 4
Author: Andrew Brock,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-29 10:55:31

Use ambos.

La función de auto invocación en la que se pasa jQuery para evitar conflictos de biblioteca, y para asegurarse de que jQuery esté disponible como se esperaría con $.

Y el .método de acceso directo ready() como se requiere para ejecutar javascript solo después de que DOM se haya cargado:

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

    //and rest of code here
})(jQuery);
 0
Author: Andrew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-12 14:38:26