61 votes

Que fait !function ($) { $(function(){ }) }(window.jQuery) ?

J'utilise twitter bootstrap pour créer un site et j'essayais d'initialiser les tooltips. A part ajouter quelque chose comme :

 $("\[rel=tooltip\]").tooltip()  dans application.js, si je ne retiens pas le morceau de code suivant utilisé dans les docs bootstrap, mes tooltips ne s'initialisent pas.

!function ($) {

  $(function(){  

  })

}(window.jQuery)

Que fait le code ci-dessus ?

162voto

Joy Points 9421

Expliquons en décomposant le code

function () {
}()

Ou souvent écrit comme

(function () {
})()

Est un self-invoking anonymous également connue sous le nom de Expressions de fonctions immédiatement déclenchées (IIFE) . qui exécute immédiatement la fonction anonyme en ligne.

Pour en savoir plus, consultez le site Expliquer la syntaxe de la fonction anonyme encapsulée. .

Les fonctions anonymes sont une fonctionnalité puissante et présentent des avantages tels que le scoping ("espacement des noms de variables"), cf. Quel est le but d'une fonction auto-exécutoire en javascript ? .


Maintenant, ils utilisent

function ($) {

}(window.jQuery)

Passons sur le ! pour l'instant.

Donc ils passent, window.jQuery dans cette fonction comme argument et en acceptant comme $ .

Ce que cela fait, c'est de rendre $ un alias pour window.jQuery (objet jQuery d'origine) et donc de s'assurer que l'objet $ fera toujours référence à la jQuery object à l'intérieur de ce closure peu importe si d'autres bibliothèques ont déjà pris cet article. $ ) à l'extérieur.

Donc le code que vous écrivez dans cette fermeture en utilisant $ fonctionnera toujours.

Un autre avantage est que $ vient en tant qu'argument dans la fonction anonyme, ce qui la rapproche dans la fonction scope chain et donc il faut moins de temps à l'interpréteur JS pour trouver l'adresse de l'utilisateur. $ à l'intérieur de la fermeture qu'il ne le ferait si nous utilisions l'objet global $ .


$(function(){  

})

Il s'agit du bloc document prêt de jQuery, comme vous le savez peut-être déjà, qui garantit que le code contenu dans cette fonction s'exécutera quand dom is ready et donc toutes les event binding's fonctionnera correctement.

Plus d'informations sur http://api.jquery.com/ready/

Et ce que ! fait a été bien expliqué aquí ou à Que fait le point d'exclamation avant la fonction ?

En bref :

Pour démontrer les avantages de ! Considérons un cas,

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

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

Si vous collez le code ci-dessus dans console vous obtiendrez deux alertes, mais ensuite vous obtiendrez cette erreur

TypeError: undefined is not a function

Pourquoi cela se produit-il ? Simulons comment les moteurs JS exécutent le bloc de code ci-dessus. Il exécute cette fonction anonyme function() {alert('first');}() montre l'alerte et comme il ne retourne rien undefined est renvoyée à l'intérieur du () . Il en va de même pour la deuxième fonction. Ainsi, après l'exécution de ce bloc, on obtient quelque chose comme

(undefined)(undefined)

et comme sa syntaxe est semblable à celle d'un self-invoking anonymous il essaie d'appeler cette fonction, mais la première, (undefined) n'est pas une fonction. Vous obtenez donc undefined is not a function erreur. ! répare ce genre d'erreurs. Ce qui se passe avec ! . Je cite les lignes du lien de la réponse ci-dessus.

Lorsque vous utilisez !, la fonction devient l'opérande unique de l'opérateur unaire (logique) NOT. (logique) unaire NOT.

Cela oblige la fonction à être évaluée comme une expression, qui permet de l'invoquer immédiatement en ligne.

et cela résout le problème ci-dessus, nous pouvons réécrire le bloc ci-dessus en utilisant ! comme

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

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

Dans votre cas, vous pouvez simplement placer le code de l'info-bulle dans un bloc prêt à l'emploi, comme ceci

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

et cela fonctionnera bien.

Et si vous utilisez juste $("[rel=tooltip]").tooltip() sans aucune doc ready block alors il y a une chance que lorsque ce code sera exécuté, il n'y aura aucun élément avec rel=tooltip dans DOM pour le moment. Donc $("[rel=tooltip]") retournera un ensemble vide et tooltip ne fonctionnera pas.

Un exemple de balisage lorsqu'il ne fonctionnera pas sans 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>

Comme les navigateurs interprètent le balisage de manière séquentielle, ils exécuteront le code js dès qu'ils le verront. Et lorsqu'il exécute le bloc JS ici, il n'a pas encore analysé le code a rel="tooltip" encore, car il apparaît après le bloc JS, donc ils ne sont pas dans le DOM à ce moment-là.

Donc, pour le cas ci-dessus $("[rel=tooltip]") est vide et donc l'info-bulle ne fonctionnera pas. Il est donc toujours prudent de placer tout votre code JS à l'intérieur du fichier document ready bloc comme

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

J'espère que tout cela a un sens pour vous maintenant.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X