2016-07-19 31 views
0

Ich verstehe, dass Nashorn kompiliert JVM-Byte-Code im laufenden Betrieb. Aber was macht Nashorn, wenn es die eval-Funktion mit einem String trifft? Kompiliert es den String-Inhalt oder interpretiert es?Erstellt Nashorn Javascript "eval" Anweisungen?

Zum Beispiel:

function sayHi() { 
    console.log("hi world"); 
} 

for (var i=0;i<10;i++) { 
    eval("sayHi()"); // what happens here? 
} 

Ein paar Optionen sein könnte: 1) es lässt sich nicht kompilieren die Zeichenfolge innerhalb eines eval 2) es einmal kompiliert, speichert es und dann wieder verwendet den gleichen Bytecode wenn es die gleiche Zeichenfolge (wie in der Schleife oben) 3) es wieder kompiliert den Inhalt eines eval String a-frisch jedes Mal

Natürlich ist dies ein kleines Beispiel, in dem der Inhalt einer Eval-Zeichenfolge ist nur ein Methodenaufruf, aber stellen Sie sich vor, es ist ein komplexerer JS-Code, der als String int übergeben wird o Eval.

+0

Es gibt wenig Sinn, 'eval()' mit einer hartkodierten Zeichenkette zu verwenden - nicht, dass 'eval()' generell empfohlen wird, aber wenn Sie * es verwenden, besteht der Punkt normalerweise darin, eine dynamisch erzeugte Zeichenkette zu übergeben mit einem Wert, der zur Kompilierzeit nicht bekannt ist. – nnnnnn

+0

Ok, nehmen wir an, dass die Zeichenfolge zu eval dynamisch ist. Wird es dann zunächst im laufenden JIT in eine temporäre Klasse kompiliert und dann sofort unbeladen. Oder wird es einfach ähnlich interpretiert wie Rhino? Oder eine andere Option? – adamM

Antwort

1

Nashorn kompiliert immer Javascript zu Bytecode für die Ausführung. Es gibt keinen Interpreter für JS. Ja, kompilierte/geladene Klassen werden entladen, wenn sie nicht von Live-Objekten aus erreichbar sind.

+0

Also, in dem obigen Beispiel, innerhalb der Schleife, jedes Mal, wenn das Eval aufgerufen wird, gibt es eine neue Rekompilierung/Entlade-Klasse, auch wenn das Eval die gleiche Zeichenfolge in der Vergangenheit angetroffen hat? – adamM

+0

Nein, es wird Cache-Treffer für denselben Code geben. d.h., wird nicht erneut neu kompiliert. Abhängig davon, ob ein aktiver Cache verfügbar ist, wird eine Kompilierung vermieden. Aber, Code wird definitiv wieder ausgeführt werden. –

+0

Also, um die Neukompilierung in der Eval (String) zu vermeiden, überprüft es gegen String.equals, um zu sehen, ob diese bestimmte Zeichenfolge bereits kompiliert wurde. Danke für Ihre kompetente Hilfe. – adamM