מבוא לנאשורן

1. הקדמה

מאמר זה מתמקד ב נאשורן - מנוע JavaScript המוגדר כברירת מחדל עבור ה- JVM החל מ- Java 8.

נעשה שימוש בטכניקות מתוחכמות רבות נאשורן בסדרי גודל יותר ביצועים ממה שקודמו כינה קַרנַף, אז זה שינוי ראוי.

בואו נסתכל על כמה מהדרכים בהן ניתן להשתמש בו.

2. שורת פיקוד

JDK 1.8 כולל מתורגמן לשורת פקודה שנקרא jjs שניתן להשתמש בהם להפעלת קבצי JavaScript או, אם הם מתחילים ללא ארגומנטים, כ- REPL (מעטפת אינטראקטיבית):

$ $ JAVA_HOME / bin / jjs hello.js שלום עולם

הנה הקובץ hello.js מכיל הוראה אחת: הדפס ("שלום עולם");

ניתן להפעיל את אותו קוד באופן אינטראקטיבי:

$ $ JAVA_HOME / bin / jjs jjs> הדפס ("שלום עולם") שלום עולם

אתה יכול גם להנחות את זמן הריצה * nix jjs להפעלת סקריפט יעד על ידי הוספת a #! $ JAVA_HOME / bin / jjs כשורה ראשונה:

#! $ JAVA_HOME / bin / jjs var greeting = "שלום עולם"; הדפס (ברכה);

ואז ניתן להריץ את הקובץ כרגיל:

$ ./hello.js שלום עולם

3. מנוע סקריפט מוטבע

הדרך השנייה וכנראה הנפוצה יותר להריץ JavaScript מתוך ה- JVM היא באמצעות ScriptEngine. JSR-223 מגדיר קבוצה של ממשקי API של scripting, המאפשרים ארכיטקטורת מנוע סקריפט ניתנת לשמש שיכולה לשמש לכל שפה דינמית (בתנאי שיש לה יישום JVM, כמובן).

בואו ניצור מנוע JavaScript:

מנוע ScriptEngine = ScriptEngineManager חדש (). GetEngineByName ("nashorn"); תוצאה של אובייקט = engine.eval ("var greeting =" שלום עולם ";" + "הדפס (ברכה);" + "ברכה");

כאן אנו יוצרים חדש ScriptEngineManager ומיד לבקש ממנו לתת לנו ScriptEngine נקרא נשורן. לאחר מכן, אנו מעבירים הוראות זוגיות ומקבלים את התוצאה אשר כצפוי, מתבררת כ- חוּטשלום עולם“.

4. העברת נתונים לתסריט

ניתן להעביר נתונים למנוע על ידי הגדרת a כריכות אובייקט והעברתו כפרמטר שני ל- הערכה פוּנקצִיָה:

כריכות כריכה = engine.createBindings (); bindings.put ("ספירה", 3); bindings.put ("שם", "באלדונג"); סקריפט מחרוזת = "var greeting =" שלום ";" + "עבור (var i = count; i> 0; i--) {" + "ברכה + = שם + ''" + "}" + "ברכה"; אובייקט bindingsResult = engine.eval (סקריפט, bindings);

הפעלת קטע זה מייצרת: “שלום baeldung baeldung baeldung“.

5. הפעלת פונקציות JavaScript

כמובן, ניתן להתקשר לפונקציות JavaScript מקוד ה- Java שלך:

engine.eval ("function composeGreeting (name) {" + "להחזיר 'שלום' + שם" + "}"); Invocable invocable = (Invocable) מנוע; אובייקט funcResult = invocable.invokeFunction ("composeGreeting", "baeldung");

זה יחזור "שלום ביילדונג“.

6. שימוש באובייקטים של Java

מכיוון שאנו פועלים ב- JVM ניתן להשתמש באובייקטים מקוריים של Java מתוך קוד JavaScript.

זה נעשה באמצעות ג'אווה לְהִתְנַגֵד:

מפת אובייקטים = engine.eval ("var HashMap = Java.type ('java.util.HashMap');" + "var map = HashMap חדש ();" + "map.put ('שלום', 'עולם') ; "+" מפה ");

7. הרחבות שפה

נאשורן מכוון ל- ECMAScript 5.1 אך הוא מספק הרחבות כדי להפוך את השימוש ב- JavaScript לטוב יותר.

7.1. איטרציה של אוספים עם For-Each

לכל אחד הוא הרחבה נוחה להקל על איטרציה על פני אוספים שונים:

סקריפט מחרוזת = "var list = [1, 2, 3, 4, 5];" + "var result = '';" + "לכל אחד (var i ברשימה) {" + "תוצאה + = i + '-';" + "};" + "הדפס (תוצאה);"; engine.eval (סקריפט);

כאן אנו מצטרפים לאלמנטים של מערך באמצעות לכל אחד מבנה איטרציה.

התפוקה המתקבלת תהיה 1-2-3-4-5-.

7.2. ספרות פונקציה

בהצהרות פונקציות פשוטות אתה יכול להשמיט סוגריים מתולתלים:

תוספת פונקציה (ב) ++ ב

ברור שזה יכול להיעשות רק עבור פונקציות פשוטות עם קו אחד.

7.3. סעיפי תפיסה מותנית

אפשר להוסיף סעיפי תפיסה שמורים שמבוצעים רק אם התנאי שצוין נכון:

נסה {לזרוק "BOOM"; } לתפוס (e אם typeof e === 'מחרוזת') {print ("מחרוזת נזרקה:" + e); } לתפוס (ה) {הדפס ("זה לא אמור לקרות!"); }

זה יודפס "מחרוזת נזרקה: בום“.

7.4. מערכים מוקלדים והמרות סוג

ניתן להשתמש במערכים שהוקלדו ב- Java ולהמיר למערכי JavaScript וממנו:

מערכי פונקציות (arr) {var javaIntArray = Java.to (arr, "int []"); הדפס (javaIntArray [0]); הדפס (javaIntArray [1]); הדפס (javaIntArray [2]); }

נאשורן מבצע כאן כמה המרות מסוג כדי לוודא שכל הערכים ממערך ה- JavaScript המוקלד באופן דינמי יכולים להשתלב במערכי Java המספרים השלמים בלבד.

התוצאה של קריאה לעיל מתפקדת עם ויכוח [100, "1654", נכון] מביא לתפוקה של 100, 1654 ו- 1 (כל המספרים).

ה חוּט וערכים בוליאניים הומרו באופן מרומז לעמיתיהם השלמים ההגיוניים.

7.5. הגדרת האב-טיפוס של אובייקט עם Object.setPrototypeOf

נאשורן מגדיר סיומת API המאפשרת לנו לשנות את אב הטיפוס של אובייקט:

Object.setPrototypeOf (obj, newProto)

פונקציה זו נחשבת בדרך כלל לחלופה טובה יותר ל- Object.prototype .__ proto__ לכן זו צריכה להיות הדרך המועדפת להגדיר את אב הטיפוס של האובייקט בכל הקוד החדש.

7.6. קִסמִי __noSuchProperty__ ו __noSuchMethod__

ניתן להגדיר שיטות על אובייקט שיופעלו בכל פעם ש- לא מוגדר נכס נכס או לא מוגדר השיטה מופעלת:

var demo = {__noSuchProperty__: function (propName) {print ("נכס שאינו קיים:" + propName); }, __noSuchMethod__: function (methodName) {print ("הוזעקה שיטה לא קיימת:" + methodName); }}; demo.doesNotExist; demo.callNonExistingMethod ()

פעולה זו תדפיס:

נכס שאינו קיים גישה: doesNotExist הוזעקה שיטה לא קיימת: callNonExistingMethod

7.7. קשירת מאפייני אובייקט עם Object.bindProperties

Object.bindProperties ניתן להשתמש כדי לקשור מאפיינים מאובייקט אחד לאחר:

var first = {name: "וויסקי", גיל: 5}; var second = {volume: 100}; Object.bindProperties (ראשון, שני); הדפס (ראשון. כרך); שנייה.נפח = 1000; הדפס (ראשון. כרך);

שימו לב, זה יוצר כריכה "חיה" וכל עדכון לאובייקט המקור גלוי גם דרך היעד המחייב.

7.8. מיקומים

ניתן להשיג את שם הקובץ, הספרייה והשורה הנוכחי ממשתנים גלובליים __FILE__, __DIR__, __LINE__:

הדפס (__ FILE__, __LINE__, __DIR__)

7.9. הרחבות ל- String.prototype

ישנן שתי הרחבות פשוטות, אך שימושיות מאוד נאשורן מספק על חוּט אב טיפוס. אלו הם trimRight ו trimLeft פונקציות אשר, באופן לא מפתיע, מחזירות עותק של ה- חוּט עם הרווח הלבן הוסר:

הדפס ("שלום עולם" .trimLeft ()); הדפס ("שלום עולם" .trimRight ());

ידפיס "שלום עולם" פעמיים ללא רווחים מובילים או נגררים.

7.10. Java.asJSON תואם פוּנקצִיָה

באמצעות פונקציה זו נוכל להשיג אובייקט התואם את ציפיות ספריות Java JSON.

כלומר שאם הוא עצמו, או כל אובייקט שניתן להגיע אליו דרכו הוא מערך JavaScript, אז אובייקטים כאלה ייחשפו כ JSObject שמיישם גם את רשימה ממשק לחשיפת רכיבי המערך.

אובייקט obj = engine.eval ("Java.asJSONCompatible ({number: 42, greet: 'hello', primes: [2,3,5,7,11,13]})"); מפת מפה = (מפה) אובייקט; System.out.println (map.get ("שלום")); System.out.println (map.get ("primes")); System.out.println (List.class.isAssignableFrom (map.get ("primes"). GetClass ()));

זה יודפס "שלום" בא אחריו [2, 3, 5, 7, 11, 13] בא אחריו נָכוֹן.

8. טעינת סקריפטים

אפשר גם לטעון קובץ JavaScript נוסף מתוך ה- ScriptEngine:

load ('classpath: script.js')

ניתן לטעון סקריפט גם מכתובת אתר:

load ('/ script.js')

זכור כי ל- JavaScript אין מושג של מרחבי שמות ולכן הכל נערם לתחום הגלובלי. זה מאפשר לסקריפטים טעונים ליצור התנגשויות שמות עם הקוד שלך או זה עם זה. ניתן למתן זאת באמצעות loadWithNewGlobal פוּנקצִיָה:

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

עם העוקבים math_module.js:

var math = {increment: function (num) {return ++ num; }}; מתמטיקה; ביי

כאן אנו מגדירים אובייקט בשם מתמטיקה שיש לה פונקציה אחת הנקראת תוֹסֶפֶת. באמצעות פרדיגמה זו אנו יכולים אפילו לחקות מודולריות בסיסית!

8. מסקנה

מאמר זה בחן כמה תכונות של נשורן ג'יימנוע avaScript. דוגמאות שהוצגו כאן בסקריפטים מילוליים של מחרוזות, אך עבור תרחישים אמיתיים, סביר להניח שאתה רוצה לשמור את הסקריפט בקבצים נפרדים ולהעמיס אותם באמצעות קוֹרֵא מעמד.

כמו תמיד, הקוד ברישום זה זמין ב- GitHub.


$config[zx-auto] not found$config[zx-overlay] not found