זהו הראשון בסדרת מאמרים על איך שפת javscript עובדת מתחת למנוע.

מנוע javascript

מחשב לא יודע להבין שום שפה מלבד שפת מכונה, כך שלמעשה המחשב לא יודע להבין את שפת ה-javascript.
על מנת שבכל זאת נוכל לצוות על המחשב שיעשה פעולות בעזרת שפת ה-javascript נוצר מנוע ה-javascript (כגון המנוע המפורסם והנפוץ - V8 של גוגל בדפדפן כרום), מנוע זה משמש כמתרגם (-translator) ותפקידו לקחת את הקוד הכתוב ב-javascript ולהמירו לקוד שהמחשב מבין.

כיוון שכל אחד יכול ליצור מנוע, ועלול להיווצר בעיות של חוסר תאימות בפיצ'רים וכדומה, נוצרה מוסכמה שנקראת ECMAScript, שאחראית לקבוע את תקני ה-javascript שכולם צריכים לעמוד ולפעול על פיהם.

מהו התהליך שמתבצע בתוך המנוע?

בתחילת התהליך המנוע מבצע ניתוח מקומי לקוד (Parser) וממירו למה שנקרא Abstract syntax tree - AST [ניתן לראות דוגמה של המרה כזאת כאן], לאחר מכן הקוד (שנמצא כרגע בצורה של AST) מעובר דרך מפרשן ומהדר - מיד יהיה פירוט על זה - כשלבסוף נפלט הקוד למחשב בצורה שהמחשב מבין אותו.

מפרשן (interpreter) ומהדר (compiler)

בדרך שבה עובד המנוע שאחראי להמיר קוד לשפה שהמחשב מבין (בכל שפות התוכנה ולאו דווקא ב-js), ישנם שתי גישות עיקריות, מפרש (interpreter) ומהדר (compiler):
מפרש לוקח את הקוד הכתוב, וקורא וממיר אותו שורה אחר שורה לפי הסדר, לקוד המבצע את אותו דבר בשפה קרובה יותר להבנה על ידי המחשב.
מהדר לעומת זאת, קורא את כל הקוד בבת אחת, מבין מה הוא אמור לבצע, וכותב בשפה קרובה יותר להבנה על ידי המחשב את מה שהקוד צריך לעשות.

למעשה, כיום משתמשים בשתי הגישות ביחד לבצע המרה של שפה (js למשל, וראה מיד בהמשך) לשפת מכונה, מכמה סיבות כשאחת מהם היא, שבדרך כלל יש כמה המרות, כל פעם לשפה שהיא בשלב קרוב יותר לשפת מכונה, וכל פעם משתמשים בגישה אחרת לפי הגישה היעילה יותר לאותו רגע.

בכל אחת מהגישות יש יתרונות וחסרונות:
היתרון של המפרש הוא ההרצה הראשונה של הקוד שהיא מהירה יותר, בגלל שכל שורה שהמפרש קורא הוא ממיר אותה מידית לביצוע, לעומת המהדר שצריך לקרוא את כל הקוד ורק אז לבצע המרה לשפה שתבצע אותו.
לעומת זאת ישנם מקרים שהמהדר יהיה יעיל יותר, כגון לולאה המבצעת הרבה פעמים את אותו הקוד, שבמהדר במקום לחזור על הקוד שוב ושוב, הוא יבין מה התוצאה צריכה להיות בסופו של דבר, ויכתוב אותה בקוד היעיל ישירות (מה שנקרא ביצוע optimization לקוד).

JIT (Just In Time) Compiler

הדרך שבה עובד מנוע ה-v8 בימינו היא עם Just In Time Compiler.
JIT Compiler עובד בצורה שהוא לוקח את המעלות משתי הגישות שכתבנו, בתחילה מריץ המנוע את הקוד בצורה של מפרשן - שורה אחר שורה - וממיר אותו ל-Bytecode, שזו היא שפה מתווכת שקרובה יותר לשפת מכונה.
אך, תוך כדי ההרצה עובד ברקע מהדר שנקראה Profiler שתפקידו לבדוק את קטע הקוד, כאשר ברגע שהוא מגלה שאפשר לעשות על הקוד אופטימיזציה (כגון לולאה שמריצה קטע קוד הרבה פעמים), הוא שולח אותו ל-Compiler, שעושה הידור לקוד ושולח קוד אופטימלי ל-Bytecode.
כך שההרצה כיום של javascript נהנית משני העולמות.

והנה איור שממחיש את התהליך:

מ239111.png