Bevezetés a Nashorn-ba
1. Bemutatkozás
Ez a cikk a következőkre összpontosít Nashorn - az új alapértelmezett JavaScript motor a JVM számára a Java 8-tól kezdve.
Számos kifinomult technikát alkalmaztak Nashorn nagyságrendekkel teljesítőbb, mint elődje nevezte Orrszarvú, tehát érdemes változás.
Vessünk egy pillantást néhány felhasználási módra.
2. Parancssor
A JDK 1.8 tartalmaz egy meghívott parancssori tolmácsot jjs amely használható JavaScript fájlok futtatására, vagy ha argumentum nélkül indult, REPL (interaktív shell) néven:
$ $ JAVA_HOME / bin / jjs hello.js Hello World
Itt a fájl hello.js egyetlen utasítást tartalmaz: nyomtatás („Hello World”);
Ugyanaz a kód futtatható interaktív módon:
$ $ JAVA_HOME / bin / jjs jjs> print ("Hello World") Hello World
Utasíthatja a * nix futásidejének használatát is jjs egy cél szkript futtatásához a hozzáadásával #! $ JAVA_HOME / bin / jjs első sorként:
#! $ JAVA_HOME / bin / jjs var greeting = "Hello Világ"; nyomtatás (üdvözlet);
Ezután a fájl a szokásos módon futtatható:
$ ./hello.js Hello World
3. Beágyazott szkript motor
A JavaScript futtatásának második és valószínűleg gyakoribb módja a JVM-en belül a ScriptEngine. A JSR-223 meghatároz egy szkript API-kat, lehetővé téve egy plug-inelhető script motor architektúrát, amely bármely dinamikus nyelvhez használható (természetesen ha rendelkezik JVM implementációval).
Hozzunk létre egy JavaScript-motort:
ScriptEngine motor = new ScriptEngineManager (). GetEngineByName ("nashorn"); Objektum eredménye = motor.eval ("var üdvözlet =" hello world ";" + "print (üdvözlet);" + "üdvözlet");
Itt létrehozunk egy újat ScriptEngineManager és azonnal kérje meg, hogy adjon nekünk egy ScriptEngine nevezett nashorn. Ezután átadunk egy pár utasítást, és megkapjuk az eredményt, amely kiszámíthatóan kiderül, hogy a Húr “Helló Világ“.
4. Adatok továbbítása a szkriptbe
Az adatok a motor definiálásával adhatók át a Kötések objektumot, és második paraméterként továbbítja a eval funkció:
Kötéskötések = motor.createBindings (); bindings.put ("count", 3); bindings.put ("név", "baeldung"); String script = "var greeting =" Hello ";" + "for (var i = count; i> 0; i--) {" + "üdvözlet + = név + ''" + "}" + "üdvözlet"; Object bindingsResult = motor.eval (szkript, összerendelések);
A kódrészlet futtatása a következőt eredményezi:Helló baeldung baeldung baeldung“.
5. JavaScript-függvények meghívása
Természetesen lehetséges Java-kódból meghívni a JavaScript-függvényeket:
engine.eval ("function composeGreeting (név) {" + "return 'Hello' + név" + "}"); Invocable invocable = (Invokálható) motor; Object funcResult = invocable.invokeFunction ("composeGreeting", "baeldung");
Ez visszatérSzia baeldung“.
6. Java objektumok használata
Mivel a JVM-ben futunk, natív Java objektumok is használhatók a JavaScript kódon belül.
Ezt úgy érhetjük el, hogy a Jáva tárgy:
Objektumtérkép = engine.eval ("var HashMap = Java.type ('java.util.HashMap');" + "var map = new HashMap ();" + "map.put ('hello', 'world') ; "+" térkép ");
7. Nyelvbővítmények
Nashorn az ECMAScript 5.1-et célozza meg de kiterjesztéseket biztosít, hogy a JavaScript használata egy kicsit szebb legyen.
7.1. Gyűjtemények itterálása mindenkinek
Az egyes egy kényelmes kiterjesztés a különböző gyűjtemények iterációjának megkönnyítésére:
Karaktersorozat = "var list = [1, 2, 3, 4, 5];" + "var result = '';" + "mindegyikhez (var i a listán) {" + "eredmény + = i + '-';" + "};" + "nyomtatás (eredmény);"; motor.eval (szkript);
Itt egy tömb elemeit egyesítjük a használatával az egyes iterációs konstrukció.
A kapott kimenet lesz 1-2-3-4-5-.
7.2. Funkció literálok
Az egyszerű függvénydeklarációkban elhagyhatja a göndör zárójeleket:
függvény növekmény (in) ++ in
Nyilvánvaló, hogy ez csak egyszerű, egysoros funkciók esetén lehetséges.
7.3. Feltételes fogási záradékok
Lehetőség van őrzött fogási záradékok hozzáadására, amelyek csak akkor teljesülnek, ha a megadott feltétel teljesül:
próbáld {dobni a "BOOM" -t; } catch (e if typeof e === 'string') {print ("String dobva:" + e); } catch (e) {print ("ennek nem szabad megtörténnie!"); }
Ez kinyomtatja aDobott húr: BOOM“.
7.4. Gépelt tömbök és típuskonverziók
Lehetséges Java tipizált tömbök használata és konvertálás JavaScript tömbökbe és azokból:
függvénytömbök (arr) {var javaIntArray = Java.to (arr, "int []"); nyomtatás (javaIntArray [0]); nyomtatás (javaIntArray [1]); nyomtatás (javaIntArray [2]); }
Nashorn néhány típusú konverziót végez itt, hogy megbizonyosodjon arról, hogy a dinamikusan beírt JavaScript tömb összes értéke elfér-e a csak egész Java-tömbökben.
A fenti függvény argumentummal történő meghívásának eredménye [100, „1654”, igaz] 100, 1654 és 1 kimenetet eredményez (minden szám).
A Húr és a logikai értékeket implicit módon konvertáltuk logikai egész megfelelőikre.
7.5. Az objektum prototípusának beállítása Object.setPrototypeOf
Nashorn meghatároz egy API kiterjesztést, amely lehetővé teszi számunkra az objektum prototípusának megváltoztatását:
Object.setPrototypeOf (obj, newProto)
Ezt a funkciót általában jobb alternatívának tekintik Object.prototype .__ proto__ így az objektum prototípusának minden új kódban történő beállításának előnyben részesített módja kell, hogy legyen.
7.6. Mágikus __noSuchProperty__ és __noSuchMethod__
Lehetőség van olyan módszerek definiálására egy objektumon, amely minden alkalommal meghívódik határozatlan ingatlanhoz hozzáfér vagy an határozatlan metódust hívják meg:
var demo = {__noSuchProperty__: function (propName) {print ("Hozzáférés a nem létező tulajdonsághoz:" + propName); }, __noSuchMethod__: function (metódusnév) {print ("Meghívott nem létező metódus:" + metódusnév); }}; demo.doesNotExist; demo.callNonExistingMethod ()
Ez kinyomtatja:
Meglévő nem létező tulajdonság: doesNotExist Meghívott nem létező módszer: callNonExistingMethod
7.7. Az objektum tulajdonságainak megkötése a Object.bindProperties
Object.bindProperties használható tulajdonságok egyik objektumból a másikba történő megkötésére:
var first = {név: "Whisky", életkor: 5}; var másodperc = {kötet: 100}; Object.bindProperties (első, második); nyomtatás (első.kötet); második.térfogat = 1000; nyomtatás (első.kötet);
Figyelje meg, hogy ez létrehoz egy „élő” kötést, és a forrásobjektum minden frissítése a kötési célponton keresztül is látható.
7.8. Helyek
Az aktuális fájlnév, könyvtár és egy sor a globális változókból szerezhető be __FILE__, __DIR__, __LINE__:
nyomtatás (__ FILE__, __LINE__, __DIR__)
7.9. A String.prototype kiterjesztései
Két egyszerű, de nagyon hasznos kiterjesztés létezik Nashorn biztosítja a Húr prototípus. Ezek trimRight és trimBal funkciók, amelyek nem meglepő módon visszaadják a Húr eltávolítva a szóközt:
print ("hello world" .trimLeft ()); print ("hello world" .trimRight ());
Kétszer kinyomtatja a „helló világot” szóköz nélkül vagy szóköz nélkül.
7.10. Java.asJSONKompatibilis Funkció
Ennek a funkciónak a használatával megszerezhetünk egy objektumot, amely kompatibilis a Java JSON könyvtárak elvárásaival.
Nevezetesen, hogy ha maga vagy bármely, rajta keresztül átmenetileg elérhető objektum egy JavaScript tömb, akkor az ilyen objektumok ki lesznek téve JSObject hogy megvalósítja a Lista interfész a tömb elemek kiállításához.
Object obj = engine.eval ("Java.asJSONCompatible ({szám: 42, üdvözlet: 'hello', prím: [2,3,5,7,11,13]})"); Térképtérkép ((Térkép) obj; System.out.println (map.get ("üdvözlet")); System.out.println (map.get ("primes")); System.out.println (List.class.isAssignableFrom (map.get ("primes"). GetClass ()));
Ez kinyomtatja aHelló”Követi [2, 3, 5, 7, 11, 13] utána igaz.
8. Szkriptek betöltése
Lehetőség van egy másik JavaScript fájl betöltésére is a ScriptEngine:
betöltés ('classpath: script.js')
A parancsfájl URL-ből is betölthető:
betöltés ('/ script.js')
Ne feledje, hogy a JavaScript nem rendelkezik a névterek fogalmával, ezért minden a globális hatókörbe kerül. Ez lehetővé teszi a betöltött parancsfájlok számára, hogy névütközéseket hozzanak létre a kóddal vagy egymással. Ez enyhíthető a loadWithNewGlobal funkció:
var math = loadWithNewGlobal ('classpath: math_module.js') math.increment (5);
A következőkkel math_module.js:
var math = {növekmény: függvény (num) {return ++ szám; }}; matek; bai
Itt definiálunk egy nevű objektumot matek amelynek egyetlen funkciója van növekedés. Ennek a paradigmának az alkalmazásával akár az alapvető modularitást is utánozhatjuk!
8. Következtetés
Ez a cikk a Nashorn JavaScript motor. Az itt bemutatott példák használt szó szerinti sztringeket tartalmaznak, de való életben a forgatókönyvet valószínűleg külön fájlokban szeretné megtartani, és egy Olvasó osztály.
Mint mindig, ebben az írásban a kód is elérhető a GitHubon.