Heim > Artikel > Web-Frontend > Detaillierte Erläuterung der Verwendung von (function(){xxx})() in js
Dieses Mal werde ich Ihnen eine detaillierte Erklärung der Verwendung von (function(){xxx})() in js geben. Was sind die Vorsichtsmaßnahmen bei der Verwendung von (function(){xxx})( ) in js? Das Folgende ist ein praktischer Fall, schauen wir uns ihn an.
SelbstausführendeAnonyme Funktion:
Gemeinsames Format: (function() { /* code */ })();
Erklärung: Das erste Klammerpaar um die Funktion (function(){}) gibt eine unbenannte Funktion an das Skript zurück, und dann führt ein leeres Klammerpaar sofort die zurückgegebene unbenannte Funktion aus. In den Klammern befinden sich die Parameter des anonymen Funktion.
Funktion: Sie können damit einen Namespace erstellen, solange Sie dann Ihren gesamten Code in dieses spezielle Funktionspaket schreiben Der Zugriff von außen ist nicht möglich, es sei denn, Sie erlauben dies (stellen Sie der Variablen „window“ voran, damit die Funktion oder Variable global wird). Der Code jeder JavaScript-Bibliothek ist grundsätzlich auf diese Weise organisiert.
Zusammenfassend sind die Hauptfunktionen der Ausführungsfunktion die anonyme und automatische Ausführung. Der Code wird bereits ausgeführt, wenn er interpretiert wird.
Andere Schreibweisen
<span style='font-family: 微软雅黑, "Microsoft YaHei"; font-size: 14px;'>(function () { /* code */ } ()); <br>!function () { /* code */ } ();<br>~function () { /* code */ } ();<br>-function () { /* code */ } ();<br>+function () { /* code */ } ();</span>
Wenn ich etwas Zeit habe In letzter Zeit kann ich mich beruhigen. Schauen wir uns verschiedene Codes an. Das häufige Erscheinen von Funktions- und Ausrufezeichen erinnert mich an die gleiche Frage, die @西子剑影 aufgeworfen hat, als ich vor 2 Monaten zum letzten Teammeeting zurückkam Sie fügen vor der Funktion ein Ausrufezeichen ein (!) Was wird passieren? Zum Beispiel der folgende Code:
<span style='font-family: 微软雅黑, "Microsoft YaHei"; font-size: 14px;'>!function(){alert('iifksp')}() // true</span>
Der nach der Ausführung auf der Konsole erhaltene Wert ist wahr. Warum er wahr ist, ist leicht zu verstehen, da diese anonyme Funktion keinen Wert zurückgibt. und der Standardrückgabewert ist undefiniert, das Negationsergebnis ist natürlich wahr. Die Frage betrifft also nicht den Ergebniswert, sondern warum kann die Negationsoperation die Selbstoptimierung einer anonymen Funktion legal machen?
Wir sind möglicherweise eher daran gewöhnt, Klammern hinzuzufügen, um anonyme Funktionen aufzurufen:
<span style='font-family: 微软雅黑, "Microsoft YaHei"; font-size: 14px;'>(function(){alert('iifksp')})() // true</span>
oder:
<span style='font-family: 微软雅黑, "Microsoft YaHei"; font-size: 14px;'>(function(){alert('iifksp')}()) // true</span>
Obwohl die Positionen der Klammern oben unterschiedlich sind, ist der Effekt genau der gleiche.
Was sind also die Vorteile, die viele Menschen dazu veranlassen, diese Ausrufezeichen-Methode zu bevorzugen? Wenn nur ein Zeichen gespeichert werden soll, ist dies zu unnötig. Selbst eine 100-KByte-Bibliothek spart möglicherweise nicht viel Platz. Da es sich nicht um Platz handelt, kann es zu Zeitüberlegungen kommen. Die Leistung wird am Ende des Artikels erwähnt.
Zurück zur Kernfrage: Warum ist das möglich? Die noch zentralere Frage ist: Warum ist das notwendig?
Tatsächlich gibt es unabhängig davon, ob es sich um Klammern oder Ausrufezeichen handelt, nur eines, was die gesamte Anweisung legal tun kann, nämlich eine Funktionsdeklarationsanweisung in einen Ausdruck umzuwandeln.
<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 | Operationen/Sek. | |||
---|---|---|---|---|---|
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 |
- | -function(){;}() | 21.553.847 | 12.135.960 | 572.694 | 1.864.155 |
~ | ~function(){;}() | 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) | (function(){;}()) | 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 |
neu | neue Funktion(){;}() | 619.606 | 299.100 | 407.104 | 816.903 |
löschen | löschfunktion(){;}() | 4.816.225 | 12.135.960 | 572.694 | 2.693.524 |
= | var i = function(){;}() | 4.984.774 | 12.135.960 | 565.982 | 2.602.630 |
&& | 1 && function(){;}() | 5.307.200 | 4.393.486 | 572.694 | 2.565.645 |
|| | 0 || Funktion(){;}() | 5.000.000 | 4.406.035 | 572.694 | 2.490.128 |
& | 1 & function(){;}() | 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 ^ function({;}() | 4.654.916 | 12.135.960 | 572.694 | 1.579.778 |
, | 1, function(){;}() | 4.878.193 | 12.135.960 | 572.694 | 2.281.186 |
Es ist ersichtlich, dass die mit verschiedenen Methoden erzielten Ergebnisse nicht gleich sind und die Unterschiede enorm sind und von Browser zu Browser variieren.
Aber wir können dennoch viele Gemeinsamkeiten feststellen: Die neue Methode ist immer die langsamste – und das ist sie natürlich auch. In vielen anderen Aspekten sind die Unterschiede eigentlich nicht groß, aber eines ist sicher: Das Ausrufezeichen ist nicht die idealste Wahl. Andererseits schneiden herkömmliche Klammern in Tests immer sehr schnell ab und sind in den meisten Fällen schneller als Ausrufezeichen – mit der von uns normalerweise verwendeten Methode gibt es also kein Problem und sie kann sogar als optimal bezeichnet werden. Die Plus- und Minuszeichen funktionieren in Chrome erstaunlich gut, sind in anderen Browsern im Allgemeinen schnell und funktionieren besser als das Ausrufezeichen.
Natürlich ist das nur ein einfacher Test und kann das Problem nicht erklären. Einige Schlussfolgerungen sind jedoch sinnvoll: Klammern sowie Plus- und Minuszeichen sind optimal.
Aber warum lieben so viele Entwickler Ausrufezeichen? Ich denke, das ist nur eine Frage der Gewohnheit und die Vor- und Nachteile zwischen ihnen können völlig ignoriert werden. Sobald Sie sich an einen Codierungsstil gewöhnt haben, verwandelt diese Konvention Ihr Programm von verwirrend in lesbar. Wenn man sich an das Ausrufezeichen gewöhnt, muss ich zugeben, dass es besser lesbar ist als Klammern. Ich muss beim Lesen nicht auf die passenden Klammern achten und beim Schreiben nicht aus Versehen vergessen -
wenn ich das Gleiche tue und dann schreie, dass das tatsächlich der Fall ist rettet einen anderen Charakter und fühlt sich selbstgefällig, vergisst aber die Peinlichkeit und Absurdität, eilig ein C-Sprachlehrbuch hervorzukramen ... Jeder vergisst manchmal, und wenn er es wieder aufgreift, ist das, was er aufgegriffen hat, nicht einfach vergessen .
Ich glaube, dass Sie die Methode beherrschen, nachdem Sie den Fall in diesem Artikel gelesen haben. Weitere spannende Informationen finden Sie in anderen verwandten Artikeln auf der chinesischen PHP-Website.
Empfohlene Lektüre:
Detaillierte Erläuterung der Anwendungsfälle der JS-Framework-Bibliothek
Wie man mit nativem JS einen Sternenhimmel erstellt Himmelseffekt
Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Verwendung von (function(){xxx})() in js. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!