Maison > interface Web > js tutoriel > le corps du texte

Explication détaillée de l'utilisation de (function(){xxx})() dans js

php中世界最好的语言
Libérer: 2018-06-04 17:35:48
original
3145 Les gens l'ont consulté

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.

JS (function(){xxx})(); analyse d'écriture

Auto-exécutableFonction anonyme :

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>
Copier après la connexion

fonction et point d'exclamation

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>
Copier après la connexion

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>
Copier après la connexion

ou :

<span style='font-family: 微软雅黑, "Microsoft YaHei"; font-size: 14px;'>(function(){alert('iifksp')}())        // true</span>
Copier après la connexion

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>
Copier après la connexion

这是一个函数声明,如果在这么一个声明后直接加上括号调用,解析器自然不会理解而报错:

<span style='font-family: 微软雅黑, "Microsoft YaHei"; font-size: 14px;'>function a(){alert('iifksp')}()        // SyntaxError: unexpected_token</span>
Copier après la connexion

因为这样的代码混淆了函数声明和函数调用,以这种方式声明的函数 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>
Copier après la connexion

赋值,逻辑,甚至是逗号,各种操作符都可以告诉解析器,这个不是函数声明,它是个函数表达式。并且,对函数一元运算可以算的上是消除歧义最快的方式,感叹号只是其中之一,如果不在乎返回值,这些一元运算都是有效的:

<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>
Copier après la connexion

甚至下面这些关键字,都能很好的工作:

<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>
Copier après la connexion

最后,括号做的事情也是一样的,消除歧义才是它真正的工作,而不是把函数作为一个整体,所以无论括号括在声明上还是把整个函数都括在里面,都是合法的:

<span style='font-family: 微软雅黑, "Microsoft YaHei"; font-size: 14px;'>(function(){alert('iifksp')})()        // undefined(function(){alert('iifksp')}())        // undefined</span>
Copier après la connexion

说了这么多,实则在说的一些都是最为基础的概念——语句,表达式,表达式语句,这些概念如同指针与指针变量一样容易产生混淆。虽然这种混淆对编程无表征影响,但却是一块绊脚石随时可能因为它而头破血流。

最后讨论下性能。我在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!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal