Frage

Es gibt zwei beliebte Abschlussstile in Javascript.Der erste, den ich anrufe anonymer Konstruktor:

new function() { 
  var code...
}

und das Inline ausgeführte Funktion:

(function() {
  var code...
})();

Gibt es Unterschiede im Verhalten zwischen diesen beiden?Ist das eine „besser“ als das andere?

War es hilfreich?

Lösung

In beiden Fällen wird die Funktion ausgeführt. Der einzige wirkliche Unterschied besteht darin, wie der Rückgabewert des Ausdrucks aussehen kann und wie der Wert von „this“ innerhalb der Funktion sein wird.

Grundsätzlich Verhalten von

new expression

Ist effektiv gleichbedeutend mit

var tempObject = {};
var result = expression.call(tempObject);
if (result is not an object)
    result = tempObject;

Obwohl tempObject und result natürlich vorübergehende Werte sind, die Sie nie sehen können (es sind Implementierungsdetails im Interpreter), und es keinen JS-Mechanismus gibt, um die Prüfung „ist kein Objekt“ durchzuführen.

Im Großen und Ganzen ist die „neue Funktion() { ..Die Methode „}“ ist langsamer, da dieses Objekt für den Konstruktor erstellt werden muss.

Dies sollte jedoch kein wirklicher Unterschied sein, da die Objektzuweisung nicht langsam ist und Sie solchen Code nicht in Hotcode verwenden sollten (aufgrund der Kosten für die Erstellung des Funktionsobjekts und den damit verbundenen Abschluss).

Bearbeiten:Eine Sache, die mir dabei aufgefallen ist, ist, dass das tempObject wird bekommen expressions Prototyp, z.(Vor dem expression.call) tempObject.__proto__ = expression.prototype

Andere Tipps

@Lanze:der erste wird auch ausgeführt.Vergleichen Sie es mit einem benannten Konstruktor:

function Blah() {
    alert('blah');
}
new Bla();

Dies führt tatsächlich auch Code aus.Das Gleiche gilt für den anonymen Konstruktor ...

Aber das war nicht die Frage ;-)

Beide erstellen einen Abschluss, indem sie den Codeblock ausführen.Aus stilistischen Gründen bevorzuge ich das zweite aus mehreren Gründen:

Auf den ersten Blick ist nicht sofort ersichtlich, dass der Code tatsächlich ausgeführt wird;die Linie sieht aus wie es ist Erstellen eine neue Funktion erstellen, anstatt sie als Konstruktor auszuführen, aber das ist nicht das, was tatsächlich passiert.Vermeiden Sie Code, der nicht das tut, was er zu tun scheint!

Auch der (function(){ ... })(); Machen Sie schöne Buchstützen-Tokens, damit Sie sofort sehen können, dass Sie einen Abschlussbereich betreten und verlassen.Das ist gut, weil es den Programmierer, der es liest, auf die Bereichsänderung aufmerksam macht, und ist besonders nützlich, wenn Sie die Datei nachbearbeiten, z. B. zur Minimierung.

Nun, ich habe eine Seite wie diese erstellt:

<html>
<body>
<script type="text/javascript">
var a = new function() { 
  alert("method 1");

  return "test";
};

var b = (function() {
  alert("method 2");

  return "test";
})();

alert(a);  //a is a function
alert(b);  //b is a string containing "test"

</script>
</body>
</html>

Überraschenderweise (zumindest für mich) wurden sowohl „Methode 1“ als auch Methode 2 gewarnt.Ich habe nicht damit gerechnet, dass „Methode 1“ benachrichtigt wird.Der Unterschied bestand in den Werten von a und b.a war die Funktion selbst, während b die Zeichenfolge war, die die Funktion zurückgab.

Im zweiten Beispiel wird die Funktion ausgeführt, nachdem sie erstellt wurde.

bearbeiten:das ist nicht wirklich wahr.

Ja, es gibt Unterschiede zwischen den beiden.

Beide sind anonyme Funktionen und werden auf genau die gleiche Weise ausgeführt.Der Unterschied zwischen beiden besteht jedoch darin, dass im zweiten Fall der Umfang der Variablen auf die anonyme Funktion selbst beschränkt ist.Es besteht keine Gefahr, dass versehentlich Variablen zum globalen Bereich hinzugefügt werden.

Dies bedeutet, dass Sie durch die Verwendung der zweiten Methode den Bereich der globalen Variablen nicht überladen, was gut ist, da diese globalen Variablenwerte einige andere globale Variablen beeinträchtigen können, die Sie möglicherweise in einer anderen Bibliothek verwenden oder in einer Bibliothek eines Drittanbieters verwendet werden .

Beispiel:

<html>
<body>
<script type="text/javascript">

new function() { 
a = "Hello";
alert(a + " Inside Function");
};

alert(a + " Outside Function");

(function() { 
var b = "World";
alert(b + " Inside Function");
})();

alert(b + " Outside Function");
</script>
</body>
</html>

Im obigen Code sieht die Ausgabe etwa so aus:

Hello Inside-Funktion
Hello Outside-Funktion
World Inside-Funktion

...dann erhalten Sie eine Fehlermeldung, da „b“ nicht außerhalb der Funktion definiert ist!

Daher glaube ich, dass die zweite Methode besser ist ...sicherer!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top