2010-01-08 16 views
18

¿Qué significa esto?una pregunta simple sobre el cierre de jquery

(function($){ 
})(jQuery); 

para hacer más clara la pregunta, ¿qué envolver una función entre paréntesis significa en JS (lo siento, estoy un poco confundido en el concepto de cierres). ¿Qué pasa con el parámetro $? y el "jQuery" en el paréntesis final?

¿Puedo hacer lo mismo con las mootools y combinarlas en 1 archivo JS?

(function($){})(jQuery); 

(function($){})(mooTools); 

Sólo he trabajado con jQuery y estoy planeando trabajar con Mootools

+0

posible duplicado de [JavaScript/jQuery sintaxis de la función de cierre] (http: // stackoverflow.com/questions/4472528/javascript-jquery-closure-function-syntax) – Matt

Respuesta

24

Envolver una función entre paréntesis asegura esta función para ser evaluado como una expresión de la función .

Eso sucede porque los Grouping Operator (entre paréntesis), sólo se puede evaluar expresiones .

Si no se utilizan paréntesis, será interpretado como una declaración función, y provocará un error de sintaxis, ya que el nombre de la función es no opcional para la declaración de funciones.

(function(arg){ 
    alert(arg); // alerts test 
})("test"); 

En el ejemplo anterior, la expresión de la función se ejecuta automáticamente, pasando un argumento.

Ese patrón es muy utilizada por los plugins jQuery, ya que jQuery se puede ejecutar en modo noConflict, no se creará la variable global $, por lo que el objeto global jQuery se pasa como argumento de esta función anónima y en el interior de esa función, puede referirse libremente a ella como $ (el argumento recibido).

Tenga en cuenta que también, el contexto de la función (la palabra clave this) dentro de las expresiones de funciones autoejecutables invocada como el ejemplo anterior, se referirá siempre al objeto Global.

Para una información más detallada acerca de las diferencias entre las expresiones de función y declaraciones de funciones, dan un aspecto a los siguientes recursos:

+0

@CMS ¿Cuál es exactamente el término correcto para esto? Lo he estado llamando una "función anónima autoejecutable" ¿Es mi término también exacto? +1 para una gran respuesta! –

+1

@Doug: Sí, creo que su término es preciso, pero recuerde que las expresiones de función también pueden tener un nombre, es simplemente opcional (es realmente útil para depurar, por ejemplo, para examinar la pila de llamadas, aunque JScript tiene errores muy serios http://groups.google.com/group/comp.lang.javascript/msg/5b508b03b004bce8 y también es útil para la recursión (ya que 'arguments.callee' en el modo estricto ES5 no estará disponible)), por lo que *" expresión de función autoejecutable " * puede ser un poco más preciso ... – CMS

+0

@CMS - ¡Increíble, gracias! –

0

function($) { ... } crea una función que acepta un parámetro llamado $.

El envolver entre paréntesis no hace nada.

Agregar (jQuery) llama a la función con jQuery como parámetro.


Esto se hace para que la función independiente de $ en el ámbito global.
Cuando se escribe $ en la función, se está refiriendo a la parámetro$, no la variable $ global.

+6

También tenga en cuenta que aunque el ajuste de una función entre paréntesis "no hace nada", es necesario si desea agregar (jQuery) después de la función. –

1

Aquí es un artículo sobre los cierres: http://www.jibbering.com/faq/faq_notes/closures.html

Básicamente, como CMS ha dicho, es una expresión de función. Hay un ejemplo perfecto para ayudarlo a comprender mejor alrededor de 2/3 del camino en esa página.

El jQuery en el último conjunto de paréntesis significa que está pasando el objeto jQuery a la función interna. Esa función interna toma el objeto y se asigna como $. Entonces, cuando está accediendo al $ dentro de la función, en realidad está actuando sobre el objeto jQuery que ha pasado.

En cuanto a mezclar estos con jQuery y Mootools, nunca he usado Mootools, así que no estoy seguro de cómo se asigna. Lo único que pensaría es que si usa $ como jQuery, puede llamar al jQuery.noConflict(); y reasignar jQuery a otra variable, tal vez var $j = jQuery; Luego, puede usar Mootools como lo haría normalmente.

6

CMS le han dado la respuesta correcta, pero solo quiero agregar que esto no es un cierre. Este es simplemente el operador() que se utiliza para devolver el resultado de una expresión que en este caso es una expresión de función y el hecho de que en javascript, se puede llamar directamente a una función anónima devuelta. Así que esto es simplemente la combinación de ambos:

var x = (1+1); // <--() evaluates an expression 

y:

var arr = [0,1,2]; 
arr.push(function(text){alert(text)}); 
arr[3]('hello'); // <-- function returned by array called directly 

Y en cuanto al parámetro $, eso es sólo uno de los personajes que javascript permite nombres de variables. Sus ejemplos es exactamente equivalente a:

(function(jQ){})(jQuery); 
(function(moo){})(mooTools); 
0

los mootools equivalente para namespacing $ es:

(function($) { 
    // $ is the mootools one (aliasing document.id) 
})(document.id); 

se pueden combinar en un solo archivo, pero tenga en cuenta que MooTools es un marco prototípico y sólo $ cumple la función de un selector, mientras que todas las funciones se incluyen en los prototipos elemento/matriz/clase, etc. por lo tanto, hacer esto en mootools funciona:

var foo = $("bar"); 
foo.hide(); // the element inherits .hide() 

pero en jQuery se producirá un error y necesita ser transcrito como

var foo = $("#bar"); 
$(foo).hide(); 

el punto es, no se puede namespace la materia que las exportaciones de MooTools en prototipos.

5

El punto principal para hacer esto es para que los objetos creados dentro de la expresión de la función puedan utilizarse desde las propiedades y los métodos asociados a los objetos pasados, sin exponer dichos objetos públicamente. Esto puede ayudar a prevenir colisiones variables. Asimismo, permite que las variables creadas para utilizarse como almacenamiento privado de cualquier cosa que se adjunta ..

(function($){ 
//jQuery is available here as $
var myPrivateArray = []; //this is private
$.addItem = function(item) { myPrivateArray.push(item); }
})(jQuery);

//I can't access myPrivateArray here... //but I can use jQuery.addItem to add something.