Cette fois, je vais vous apporter une explication détaillée de l'utilisation de (function(){xxx})() dans js Quelles sont les précautions lors de l'utilisation de (function(){xxx})(. ) en js ? Voici ce qui suit : C'est un cas pratique, jetons-y un coup d'œil.
Auto-exécutableFonction anonyme :
Format commun : (function() { /* code */ })();
Explication : La première paire de crochets entourant la fonction (function(){}) renvoie une fonction sans nom au script, puis une paire de crochets vides exécute immédiatement la fonction sans nom renvoyée. À l'intérieur des parenthèses se trouvent les paramètres de l'anonyme <.>fonction.
Fonction : vous pouvez l'utiliser pour créer un espace de noms , à condition d'écrire tout votre code dans ce package de fonctions spécial, puis Il n'est pas accessible de l'extérieur sauf si vous l'autorisez (préfixez la variable avec window pour que la fonction ou la variable devienne globale). Le code de chaque bibliothèque JavaScript est essentiellement organisé de cette manière.
Pour résumer, les principales fonctions de la fonction d'exécution sont l'exécution anonyme et automatique. Le code est déjà en cours d'exécution lorsqu'il est interprété.
Autres façons d'écrire
<span style='font-family: 微软雅黑, "Microsoft YaHei"; font-size: 14px;'>(function () { /* code */ } ()); <br>!function () { /* code */ } ();<br>~function () { /* code */ } ();<br>-function () { /* code */ } ();<br>+function () { /* code */ } ();</span>
Si vous avez récemment, vous pouvez me faire savoir que je me suis calmé et que j'ai jeté un œil à divers codes. L'apparition fréquente de fonctions et de points d'exclamation m'a rappelé la même question soulevée par @西子剑影 lors de mon retour à Hangzhou pour la dernière réunion d'équipe 2. il y a des mois : Si vous ajoutez une fonction avant une fonction Que se passe-t-il si vous mettez un point d'exclamation (!) ? Par exemple, le code suivant :
<span style='font-family: 微软雅黑, "Microsoft YaHei"; font-size: 14px;'>!function(){alert('iifksp')}() // true</span>
La valeur obtenue après exécution sur la console est vraie. Pourquoi c'est vrai est facile à comprendre, car cette fonction anonyme n'a aucune valeur de retour. et est renvoyé par défaut. Il n'est pas défini et le résultat de la négation est naturellement vrai. La question ne concerne donc pas la valeur du résultat, mais pourquoi l'opération de négation peut-elle rendre légal l'auto-réglage d'une fonction anonyme ?
On est peut-être plus habitué à ajouter des parenthèses pour appeler des fonctions anonymes :
<span style='font-family: 微软雅黑, "Microsoft YaHei"; font-size: 14px;'>(function(){alert('iifksp')})() // true</span>
ou :
<span style='font-family: 微软雅黑, "Microsoft YaHei"; font-size: 14px;'>(function(){alert('iifksp')}()) // true</span>
Bien que les positions des supports ci-dessus soient différentes, l'effet est exactement le même.
Alors, quels sont les avantages qui font que de nombreuses personnes préfèrent cette méthode du point d'exclamation ? S'il s'agit simplement de sauvegarder un caractère, c'est trop inutile. Même une bibliothèque de 100 Ko peut ne pas économiser beaucoup d'espace. Puisqu'il ne s'agit pas d'espace, cela signifie qu'il peut y avoir des considérations de temps. Les faits sont difficiles à dire. Les performances sont mentionnées à la fin de l'article.
Retour à la question centrale, pourquoi cela peut-il être fait ? La question encore plus centrale est : pourquoi est-ce nécessaire ?
En fait, qu'il s'agisse de parenthèses ou de points d'exclamation, il n'y a qu'une seule chose que l'instruction entière peut légalement faire, c'est de transformer une instruction de déclaration de fonction en une expression.
<span style='font-family: 微软雅黑, "Microsoft YaHei"; font-size: 14px;'>function a(){alert('iifksp')} // undefined</span>
这是一个函数声明,如果在这么一个声明后直接加上括号调用,解析器自然不会理解而报错:
<span style='font-family: 微软雅黑, "Microsoft YaHei"; font-size: 14px;'>function a(){alert('iifksp')}() // SyntaxError: unexpected_token</span>
因为这样的代码混淆了函数声明和函数调用,以这种方式声明的函数 a,就应该以 a(); 的方式调用。
但是括号则不同,它将一个函数声明转化成了一个表达式,解析器不再以函数声明的方式处理函数a,而是作为一个函数表达式处理,也因此只有在程序执行到函数a时它才能被访问。
所以,任何消除函数声明和函数表达式间歧义的方法,都可以被解析器正确识别。比如:
<span style='font-family: 微软雅黑, "Microsoft YaHei"; font-size: 14px;'>var i = function(){return 10}(); // undefined 1 && function(){return true}(); // true 1, function(){alert('iifksp')}(); // undefined</span>
赋值,逻辑,甚至是逗号,各种操作符都可以告诉解析器,这个不是函数声明,它是个函数表达式。并且,对函数一元运算可以算的上是消除歧义最快的方式,感叹号只是其中之一,如果不在乎返回值,这些一元运算都是有效的:
<span style='font-family: 微软雅黑, "Microsoft YaHei"; font-size: 14px;'>!function(){alert('iifksp')}() // true+function(){alert('iifksp')}() // NaN-function(){alert('iifksp')}() // NaN~function(){alert('iifksp')}() // -1</span>
甚至下面这些关键字,都能很好的工作:
<span style='font-family: 微软雅黑, "Microsoft YaHei"; font-size: 14px;'>void function(){alert('iifksp')}() // undefined new function(){alert('iifksp')}() // Object delete function(){alert('iifksp')}() // true</span>
最后,括号做的事情也是一样的,消除歧义才是它真正的工作,而不是把函数作为一个整体,所以无论括号括在声明上还是把整个函数都括在里面,都是合法的:
<span style='font-family: 微软雅黑, "Microsoft YaHei"; font-size: 14px;'>(function(){alert('iifksp')})() // undefined(function(){alert('iifksp')}()) // undefined</span>
说了这么多,实则在说的一些都是最为基础的概念——语句,表达式,表达式语句,这些概念如同指针与指针变量一样容易产生混淆。虽然这种混淆对编程无表征影响,但却是一块绊脚石随时可能因为它而头破血流。
最后讨论下性能。我在jsperf上简单建立了一个测试:http://jsperf.com/js-funcion-expression-speed ,可以用不同浏览器访问,运行测试查看结果。我也同时将结果罗列如下表所示(由于我比较穷,测试配置有点丢人不过那也没办法:奔腾双核1.4G,2G内存,win7企业版):
Option | Code | Ops/sec | |||
---|---|---|---|---|---|
Chrome 13 | Firefox 6 | IE9 | Safari 5 | ||
! | !function(){;}() | 3 773 196 | 10 975 198 | 572 694 | 2 810 197 |
+ | +function(){;}() | 21 553 847 | 12 135 960 | 572 694 | 1 812 238 |
- | -fonction(){;}() | 21 553 847 | 12 135 960 | 572 694 | 1 864 155 |
~ | ~fonction(){;}() | 3 551 136 | 3 651 652 | 572 694 | 1 876 002 |
(1) | (function(){;})() | 3 914 953 | 12 135 960 | 572 694 | 3 025 608 |
(2) | (fonction(){;}()) | 4 075 201 | 12 135 960 | 572 694 | 3 025 608 |
void | void function(){;}() | 4 030 756 | 12 135 960 | 572 694 | 3 025 608 |
nouvelle | nouvelle fonction(){;}() | 619 606 | 299 100 | 407 104 | 816 903 |
supprimer | supprimer la fonction(){;}() | 4 816 225 | 12 135 960 | 572 694 | 2 693 524 |
= | var i = fonction(){;}() | 4 984 774 | 12 135 960 | 565 982 | 2 602 630 |
&& | 1 && fonction(){;}() | 5 307 200 | 4 393 486 | 572 694 | 2 565 645 |
|| | 0 || fonction(){;}() | 5 000 000 | 4 406 035 | 572 694 | 2 490 128 |
& | 1 & fonction(){;}() | 4 918 209 | 12 135 960 | 572 694 | 1 705 551 |
| | 1 | function(){;}() | 4 859 802 | 12 135 960 | 572 694 | 1 612 372 |
^ | 1 ^ fonction(){;}() | 4 654 916 | 12 135 960 | 572 694 | 1 579 778 |
, | 1, fonction(){;}() | 4 878 193 | 12 135 960 | 572 694 | 2 281 186 |
On peut voir que les résultats produits par différentes méthodes ne sont pas les mêmes, et les différences sont énormes et varient d'un navigateur à l'autre.
Mais nous pouvons encore trouver de nombreux points communs entre eux : la nouvelle méthode est toujours la plus lente - et bien sûr, elle l'est. Sur de nombreux autres aspects, les différences ne sont en réalité pas grandes, mais une chose est sûre, le point d’exclamation n’est pas le choix le plus idéal. D'un autre côté, les parenthèses traditionnelles fonctionnent toujours très rapidement dans les tests et, dans la plupart des cas, sont plus rapides que les points d'exclamation - il n'y a donc aucun problème avec la méthode que nous utilisons habituellement, et elle peut même être considérée comme optimale. Les signes plus et moins fonctionnent étonnamment dans Chrome et sont généralement rapides dans d'autres navigateurs, et ils fonctionnent mieux que le point d'exclamation.
Bien sûr, il ne s'agit que d'un simple test et ne peut pas expliquer le problème. Mais certaines conclusions ont du sens : les parenthèses et les signes plus et moins sont optimaux.
Mais pourquoi tant de développeurs aiment-ils les points d'exclamation ? Je pense que c'est juste une question d'habitude, et les avantages et les inconvénients entre eux peuvent être complètement ignorés. Une fois que vous vous serez habitué à un style de codage, cette convention transformera votre programme de déroutant en lisible. Si vous vous habituez au point d’exclamation, je dois admettre qu’il est plus lisible que les parenthèses. Je n'ai pas besoin de faire attention aux parenthèses correspondantes lors de la lecture, et je n'ai pas besoin d'oublier accidentellement en écrivant -
quand je fais de même et que je crie que c'est en fait sauve un autre personnage et se sent suffisant, mais a oublié l'embarras et l'absurdité de déterrer à la hâte un manuel de langage C roulé... Tout le monde oublie parfois, et quand il le reprend, ce qu'il a ramassé n'est pas simplement quelque chose d'oublié. .
Je pense que vous maîtrisez la méthode après avoir lu le cas dans cet article. Pour des informations plus intéressantes, veuillez prêter attention aux autres articles connexes sur le site Web chinois de php !
Lecture recommandée :
Explication détaillée des cas d'utilisation de la bibliothèque de framework JS
Comment utiliser le js natif pour créer un étoilé effet ciel
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!