Uvod u Nashorn

1. Uvod

Ovaj je članak usredotočen na Nashorn - novi zadani JavaScript mehanizam za JVM od Jave 8.

Za izradu su korištene mnoge sofisticirane tehnike Nashorn redoslijed veličina učinkovitiji nego što se zvao njegov prethodnik Nosorog, pa je to vrijedna promjena.

Pogledajmo neke od načina na koje se može koristiti.

2. Naredbeni redak

JDK 1.8 uključuje tumač naredbenog retka koji se naziva jjs koji se može koristiti za pokretanje JavaScript datoteka ili, ako je pokrenut bez argumenata, kao REPL (interaktivna ljuska):

$ $ JAVA_HOME / bin / jjs hello.js Pozdrav svijetu

Evo datoteke bok.js sadrži jednu uputu: ispis (“Hello World”);

Isti se kôd može pokrenuti na interaktivan način:

$ $ JAVA_HOME / bin / jjs jjs> print ("Hello World") Zdravo Svijet

Također možete uputiti runtime * nix da se koristi jjs za pokretanje ciljne skripte dodavanjem a #! $ JAVA_HOME / bin / jjs kao prvi redak:

#! $ JAVA_HOME / bin / jjs var pozdrav = "Pozdrav svijetu"; ispis (pozdrav);

I tada se datoteka može pokrenuti kao i obično:

$ ./hello.js Pozdrav svijetu

3. Ugrađeni skriptni mehanizam

Drugi i vjerojatno češći način pokretanja JavaScripta iz JVM-a je putem ScriptEngine. JSR-223 definira skup API-ja za skriptiranje, omogućavajući arhitekturu mehanizma skripti koji se može priključiti i koja se može koristiti za bilo koji dinamički jezik (pod uvjetom da ima JVM implementaciju, naravno).

Stvorimo JavaScript mehanizam:

ScriptEngine engine = novi ScriptEngineManager (). GetEngineByName ("nashorn"); Rezultat objekta = engine.eval ("var pozdrav =" pozdrav svijetu ";" + "ispis (pozdrav);" + "pozdrav");

Ovdje stvaramo novo ScriptEngineManager i odmah zatražite da nam da a ScriptEngine imenovan nashorn. Zatim, proslijedimo nekoliko uputa i dobijemo rezultat koji se, predvidljivo, pokazao kao NizPozdrav svijete“.

4. Prosljeđivanje podataka u skriptu

Podaci se mogu proslijediti u motor definiranjem a Vezovi objekt i prosljeđuje ga kao drugi parametar eval funkcija:

Vezovi vezovi = engine.createBindings (); bindings.put ("count", 3); bindings.put ("ime", "baeldung"); String skripta = "var pozdrav =" Pozdrav ";" + "for (var i = count; i> 0; i--) {" + "pozdrav + = ime + ''" + "}" + "pozdrav"; Vezi predmetaResult = engine.eval (skripta, vezovi);

Pokretanje ovog isječka daje: “Pozdrav baeldung baeldung baeldung“.

5. Pozivanje JavaScript funkcija

Jasno je da je moguće pozvati JavaScript funkcije s vašeg Java koda:

engine.eval ("function composeGreeting (name) {" + "return 'Hello' + name" + "}"); Invocable invocable = (Invocable) motor; Objekt funcResult = invocable.invokeFunction ("composeGreeting", "baeldung");

Ovo će se vratiti “Pozdrav baeldung“.

6. Korištenje Java objekata

Budući da radimo u JVM-u, moguće je koristiti izvorne Java objekte unutar JavaScript koda.

To se postiže pomoću a Java objekt:

Mapa objekta = engine.eval ("var HashMap = Java.type ('java.util.HashMap');" + "var map = new HashMap ();" + "map.put ('hello', 'world') ; "+" karta ");

7. Proširenja jezika

Nashorn cilja ECMAScript 5.1 ali nudi proširenja kako bi korištenje JavaScript-a bilo malo ljepše.

7.1. Ponavljanje zbirki pomoću for-each

Za svakoga prikladno je proširenje za olakšavanje iteracije različitih zbirki:

String skripta = "var list = [1, 2, 3, 4, 5];" + "var rezultat = '';" + "za svaku (var i na popisu) {" + "rezultat + = i + '-';" + "};" + "ispis (rezultat);"; motor.eval (skripta);

Ovdje pridružujemo elemente niza pomoću za svakoga konstrukcija iteracije.

Rezultirajući izlaz bit će 1-2-3-4-5-.

7.2. Književnost funkcije

U jednostavnim deklaracijama funkcija možete izostaviti kovrčave zagrade:

prirast funkcije (in) ++ in

Očito je da se to može učiniti samo za jednostavne, jednoslojne funkcije.

7.3. Klauzule o uvjetnom ulovu

Moguće je dodati zaštićene klauzule klauzule koje se izvršavaju samo ako je navedeni uvjet istinit:

pokušajte {baciti "BOOM"; } catch (e ako typeof e === 'string') {print ("Izbačen niz:" + e); } catch (e) {print ("ovo se ne bi smjelo dogoditi!"); }

Ovo će ispisati "Bačen niz: BOOM“.

7.4. Tipizirani nizovi i pretvorbe tipova

Moguće je koristiti nizove upisane u Javi i pretvoriti u i iz JavaScript nizova:

nizovi funkcija (arr) {var javaIntArray = Java.to (arr, "int []"); ispis (javaIntArray [0]); ispis (javaIntArray [1]); ispis (javaIntArray [2]); }

Nashorn ovdje izvodi neke pretvorbe tipova kako bi bio siguran da se sve vrijednosti iz dinamički tipkanog JavaScript niza mogu uklopiti u cjelovite samo Java nizove.

Rezultat pozivanja gornje funkcije s argumentom [100, „1654“, istina] rezultira rezultatom 100, 1654 i 1 (svi brojevi).

The Niz i logičke vrijednosti implicitno su pretvorene u svoje logičke cjeline.

7.5. Postavljanje prototipa objekta sa Object.setPrototypeOf

Nashorn definira API proširenje koje nam omogućuje promjenu prototipa objekta:

Object.setPrototypeOf (obj, newProto)

Ova se funkcija općenito smatra boljom alternativom Objekt.prototip .__ proto__ pa bi to trebao biti preferirani način postavljanja prototipa objekta u svim novim kodovima.

7.6. Čarobno __noSuchProperty__ i __noSuchMethod__

Moguće je definirati metode na objektu koje će se pozivati ​​kad god nedefiniran nekretnini se pristupa ili nedefiniran poziva se metoda:

var demo = {__noSuchProperty__: function (propName) {print ("Pristupljeno nepostojećem svojstvu:" + propName); }, __noSuchMethod__: function (methodName) {print ("Pozvana nepostojeća metoda:" + imeName); }}; demo.doesNotExist; demo.callNonExistingMethod ()

Ovo će ispisati:

Pristupljeno nepostojećem svojstvu: doesNotExist Pozvana nepostojeća metoda: callNonExistingMethod

7.7. Poveži svojstva objekta sa Object.bindProperties

Object.bindProperties može se koristiti za povezivanje svojstava iz jednog objekta u drugi:

var prvi = {naziv: "Viski", dob: 5}; var drugo = {volumen: 100}; Object.bindProperties (prva, druga); ispis (prvi.glas); drugo.glas = 1000; ispis (prvi.glas);

Primijetite, ovo stvara "živo" povezivanje, a sva ažuriranja izvornog objekta također su vidljiva kroz cilj povezivanja.

7.8. Lokacije

Trenutni naziv datoteke, direktorij i redak mogu se dobiti od globalnih varijabli __FILE__, __DIR__, __LINE__:

ispis (__ FILE__, __LINE__, __DIR__)

7.9. Proširenja za String.prototype

Postoje dva jednostavna, ali vrlo korisna proširenja koja Nashorn pruža na Niz prototip. Ovi su trimRight i trimLeft funkcije koje, što nije iznenađujuće, vraćaju kopiju Niz s uklonjenim razmakom:

ispis ("hello world" .trimLeft ()); ispis ("hello world" .trimRight ());

Dvaput će ispisati "hello world" bez vodećih ili pratećih razmaka.

7.10. Java.asJSONKompatibilan Funkcija

Korištenjem ove funkcije možemo dobiti objekt koji je kompatibilan s očekivanjima Java JSON knjižnica.

Naime, ako je sam ili bilo koji objekt koji je kroz njega prijelazno dostupan JavaScript niz, tada će takvi objekti biti izloženi kao JSObject koja također provodi Popis sučelje za izlaganje elemenata niza.

Objekt obj = engine.eval ("Java.asJSONCompatible ({broj: 42, pozdrav: 'zdravo', prosti brojevi: [2,3,5,7,11,13]})" "; Karta karte = (Map) obj; System.out.println (map.get ("greet")); System.out.println (map.get ("prosti brojevi")); System.out.println (List.class.isAssignableFrom (map.get ("primees"). GetClass ()));

Ovo će ispisati "zdravo”Slijedi [2, 3, 5, 7, 11, 13] nakon čega slijedi pravi.

8. Učitavanje skripti

Također je moguće učitati drugu JavaScript datoteku iz ScriptEngine:

load ('classpath: script.js')

Skripta se također može učitati s URL-a:

učitavanje ('/ script.js')

Imajte na umu da JavaScript nema koncept prostora imena pa se sve nagomilava u globalni opseg. To omogućuje da učitane skripte stvaraju sukobe u imenovanju s vašim kodom ili međusobno. To se može ublažiti korištenjem loadWithNewGlobal funkcija:

var math = loadWithNewGlobal ('classpath: math_module.js') math.increment (5);

Uz sljedeće math_module.js:

var math = {prirast: funkcija (num) {return ++ num; }}; matematika; bai

Ovdje definiramo objekt s imenom matematika koja ima jednu funkciju koja se naziva prirast. Koristeći ovu paradigmu možemo čak oponašati osnovnu modularnost!

8. Zaključak

Ovaj je članak istraživao neke značajke Nashorn JavaScript motor. Ovdje su prikazani primjeri korištenih skripti literalnih nizova, ali za stvarne scenarije najvjerojatnije želite svoju skriptu zadržati u zasebnim datotekama i učitati ih pomoću Čitač razred.

Kao i uvijek, kôd u ovom zapisu dostupan je na GitHubu.