Funktionskonstruktor gegen Funktionsanweisung

8

heute Ich habe gelesen, dass wir eine Möglichkeit haben, die Funktion vom Function-Konstruktor zu deklarieren . Aber ich habe nie die tatsächliche Implementierung gesehen, die Function Konstruktor in real verwendet. Also möchte ich fragen, gibt es irgendwelche Umstände, die wir nutzen können, indem wir Function constructor verwenden anstatt function() deklaration? Und was sind die versteckten Unterschiede zwischen? (Wenn es welche gibt)

Funktionskonstruktor

%Vor%

function ():

%Vor%

Danke

    
c4il 26.09.2010, 18:50
quelle

4 Antworten

10

Der Konstruktor function ist eine Form von eval , die generell vermieden werden sollte (sie ist langsam und wird als unsicher angesehen). Es gibt keinen Vorteil, den Konstruktor Function über die eingebaute Funktionsanweisung zu verwenden, es sei denn, Sie möchten eine Funktion aus dynamischen Komponenten konstruieren, was ziemlich selten ist. Es gibt legitime Verwendungen für diese Form, jedoch wird die meiste Zeit unnötigerweise verwendet, weshalb sie herabgesehen und im Allgemeinen vermieden wird.

Außerdem behalten Funktionen, die mit dem Funktionskonstruktor erstellt wurden, keinen Verweis auf die Umgebung, in der sie definiert wurden (die Schließung). Wenn sie ausgeführt werden, ziehen sie diese Variablen direkt aus dem globalen Gültigkeitsbereich.

%Vor%

Während reguläre Funktionen einen Verweis auf die Umgebung behalten, in der sie definiert wurden:

%Vor%     
Cristian Sanchez 26.09.2010, 18:54
quelle
2

Nun, der offensichtliche Unterschied bei der Arbeit mit Zeichenketten ist, dass Sie die Möglichkeit haben, eine Meta-Programmierung durchzuführen, indem Sie die Zeichenkette zur Laufzeit konstruieren (das gleiche wie mit eval ). Dies ist jedoch zweischneidig und führt wohl zu einer Reihe anderer Probleme mit wörtlicher Verkettung (Injektion) und vielleicht einfach Komplexität. Wenn Sie die Zeichenfolgenversion nicht brauchen , würde ich sie nicht verwenden, um ehrlich zu sein.

Ein Nebeneffekt der regulären (Nicht-String-) Version ist, dass die meisten Javascript-Minifier (oder Obfuscatoren) wissen, was damit zu tun ist. Dies scheint für die Saite unwahrscheinlich, d. H. Sie lassen sie "wie sie ist" (nicht minimiert oder verschleiert).

    
Marc Gravell 26.09.2010 18:53
quelle
2

Wenn Sie einen Javascript-Parser schreiben und einen String als Funktion interpretieren, können Sie einen Funktionskonstruktor verwenden. ZB wenn Sie gegeben sind:

%Vor%

Und Sie haben eine Art lexikalischen Parser und finden, dass Teilstring tatsächlich eine Funktion ist, um sie in eine echte Funktion zu übersetzen, würden Sie new Function verwenden und sie zu Ihrem Baum hinzufügen.

Sonst gibt es wirklich keinen großen Nutzen, den ich mir vorstellen kann.

    
meder omuraliev 26.09.2010 18:53
quelle
0

Zusätzliche Anmerkungen zu Cristian Sanchez 'Posting.

Sie können innerhalb einer 'Funktions'-Auswertung niemals auf lokale Bereichsvariablen zugreifen.

Sehen wir uns den Unterschied zwischen Funktion und eval an.

Funktionsbeispiel:

%Vor%

Der Function-Konstruktor weiß nichts über den lokalen Bereich, weil er einen neuen isolierten Bereich unter dem window / global-Objekt erstellt - nicht an der Position, wo er ist - das ist der Hauptunterschied zu eval.

Eval-Beispiel:

%Vor%

'eval' hat Zugriff auf die lokalen Variablen. Selbst wenn Sie die ganze Sache abgrenzen.

%Vor%

Im folgenden Beispiel gibt f () einen Fehler aus - "a" ist in seinem eigenen (und globalen) Gültigkeitsbereich nicht definiert. Der Function-Konstruktor hat seinen eigenen speziellen Gültigkeitsbereich, ohne etwas außerhalb zu wissen - außer seinem übergeordneten Gültigkeitsbereich - dem window / global-object.

%Vor%

Wenn Sie lokale Variablen verwenden möchten, übergeben Sie sie als Parameter an den Funktionskonstruktor innerhalb des inneren Bereichs!

%Vor%

oder

%Vor%

Sie können Function auch direkt mit call / apply ausführen (kein "new" benötigt).

%Vor%

Übrigens ist es immer empfehlenswert, den strikten Modus zu setzen, um das korrekte ES5-Verhalten zu aktivieren.

Bei strict-mode ist 'this' standardmäßig (korrekt) undefiniert - bis Sie ein Objekt binden.

%Vor%

Wenn Sie möchten, können Sie 'this' explizit binden

%Vor%

Natürlich können Sie jede Funktion / jedes Klassenobjekt an Objekte erweitern.

%Vor%

Gleiches Ergebnis mit direktem Aufruf, ohne 'neues' Schlüsselwort.

%Vor%

Jede Funktion / Klasse wird durch den 'Function'-Konstruktor erstellt.

Sie müssen also in Ihrem Code nicht "Funktion" schreiben. Sie können auch das Konstruktor-Objekt verwenden.

%Vor%

Die Verwendung von "Function" ist zB gut für Spiele, wenn Sie einen XMLHttpRequest-Preloader haben, der eine sehr große Javascript-Datei lädt (5-10 MB gebündelte Skripte), während Sie eine Lade-Leiste anzeigen lassen oder etwas anderes für den Benutzer, stattdessen das ganze Ding mit einem Skript-Tag zu laden, während der Benutzer auf das Laden der Seite ohne visuelle Antwort wartet.

Es spielt keine Rolle, ob Sie ein großes Skript über ein Skript-Tag oder über die Funktion beim Start laden. Die Engine muss den Plain-Code laden und in beide Richtungen auswerten. Es gibt keine Sicherheitsaspekte, wenn Ihr (!) Code von einer vertrauenswürdigen Quelle (Ihrer Domain) stammt und Sie wissen, was drin ist.

'Funktion' und 'eval' sind nur schlecht mit nicht vertrauenswürdigem Code (wenn andere Benutzer Einfluss darauf haben) oder in Loops (langsame Performance durch Kompilierung), aber es ist völlig in Ordnung, load & amp; Bewerten Sie Ihre eigenen Skripte beim Start, wenn der Code derselbe wie in externen Javascript-Dateien ist.

    
SammieFox 25.04.2017 18:18
quelle

Tags und Links