2012-06-05 16 views
58

Estoy usando twitter bootstrap para crear un sitio y estaba tratando de inicializar información sobre herramientas. Además de agregar algo como:

 $("[rel=tooltip]").tooltip()
en application.js, a menos que conserve, el siguiente fragmento de código utilizado en los documentos de arranque, mis tooltips no se inicializan.

 
!function ($) { 

    $(function(){ 

    }) 

}(window.jQuery) 

¿Qué hace el código anterior?

Respuesta

157

Permite explicar mediante la ruptura del código

function() { 
}() 

O escrito a menudo como

(function() { 
})() 

es una función self-invoking anonymous, también conocido como Expresiones función invocada Inmediatamente-(IIFEs). Que ejecuta la función anónima en línea inmediatamente.

Lea más acerca de esto en Explain the encapsulated anonymous function syntax.

Las funciones anónimas son una característica poderosa y tienen beneficios como el alcance ("espaciado variable de nombre"), consulte What is the purpose of a self executing function in javascript?.


Ahora se están utilizando

function ($) { 

}(window.jQuery) 

Vamos a saltar la ! por ahora.

Así que están pasando, window.jQuery en esa función como argumento y aceptando como $.

Lo que esto hace es hacer $ un alias para window.jQuery (objeto original jQuery) y por lo tanto asegurar que el $ se referirá siempre a la jQuery object dentro de esa closure, no importa si otra biblioteca que ha tomado ($) fuera.

Así que el código que escriba dentro de ese cierre usando $ siempre funcionará.

Otra ventaja es que $ viene como argumento en la función anónima, que lo acerca en el scope chain y por lo tanto se tarda menos tiempo para el intérprete JS para encontrar el objeto $ dentro del cierre de lo que debería tomaron si utilizado el mundial $.


$(function(){ 

}) 

Es bloque de lista de documentos de jQuery como usted ya sabe, lo que garantiza que el código dentro de esta función se ejecutará cuando dom is ready, y por lo tanto todo event binding's funcionará correctamente.

Ver más en http://api.jquery.com/ready/

Y lo que ! qué ha sido bien explicada here o al What does the exclamation mark do before the function?

En breve:

para demostrar los beneficios de !, vamos a considerar un caso,

(function() { 
    alert('first'); 
}()) 


(function() { 
    alert('second'); 
}()) 

Si pega el código anterior en console, obtendrá dos alertas, pero por lo que recibirá este error

TypeError: undefined is not a function 

¿Por qué sucede esto? Simulemos cómo los motores JS ejecutan el bloque de código anterior. Ejecuta esta función anónima function() {alert('first');}() muestra la alerta y como devuelve nada undefined se devuelve dentro del (). Lo mismo ocurre con la segunda función también. Así que después de la ejecución de este bloque, se termina por tener algo así como

(undefined)(undefined) 

y como es la sintaxis es como una función self-invoking anonymous, que trata de llamar a esa función, pero la primera, (undefined) no es una función. Entonces obtienes el error undefined is not a function. ! corrige este tipo o errores. Qué pasa con !. Estoy citando las líneas del enlace de respuesta anterior.

Cuando utiliza!, La función se convierte en el único operando del operador (lógico) NOT unitario.

Esto fuerza a la función a evaluarse como una expresión, que permite que se invoque inmediatamente en línea.

y esto resuelve el problema anterior, podemos reescribir el bloque anterior utilizando ! como

!(function() { 
    alert('first'); 
}()) 


!(function() { 
    alert('second'); 
}()) 

Para su caso, puede simplemente poner el código de información de herramienta dentro de un bloque listo documento como este

$(function(){ 
    $("[rel=tooltip]").tooltip(); 
}); 

y funcionará bien.

Y si solo usa $("[rel=tooltip]").tooltip() sin ninguna doc ready block, entonces existe la posibilidad de que cuando se ejecute este código, todavía no haya ningún elemento con rel=tooltip en DOM. Por lo tanto, $("[rel=tooltip]") devolverá un conjunto vacío y tooltip no funcionará.

Un ejemplo de marcado cuando no funcionará sin doc ready block,

. 
. 
. 
<script type="text/javascript"> 
    $("[rel=tooltip]").tooltip(); 
</script> 
. 
. 
. 
. 
<a href="#" rel="tooltip">Something</a> 
<a href="#" rel="tooltip">Something</a> 
<a href="#" rel="tooltip">Something</a> 

Como los navegadores, interpreta la secuencia de marcado, se ejecutará el código JS tan pronto como la cara él como. Y cuando ejecuta el bloque JS aquí, todavía no ha analizado las etiquetas a rel="tooltip", como aparece después del bloque JS, por lo que no están en DOM en ese momento.

Por lo tanto, para el caso anterior $("[rel=tooltip]") está vacío y, por lo tanto, la información sobre herramientas no funcionará. Así que siempre es seguro para poner todo el código JS dentro document ready bloque como

$(function){ 
    // put all your JS code here 
}); 

Espero que todo esto tenga sentido para usted ahora.

+5

¡Gracias por la gran respuesta! – powtac

+0

@powtac, gracias, también soy un novato aprendiendo cosas nuevas en JS todos los días desde SO. –

+4

+1 Gran escritura, aprendí un poco aquí. Creo que esto se conoce como una * Respuesta canónica * :) – brasofilo