Dev-Time

ES6 – בעברית: Temporal Dead Zone and Let vs Var

הקדמה

אז לפני שנצלול לעומק נתחיל בקרב הידוע לשמצה Let vs Var בהצלחה! , let/const הגיחו לעולם הJavaScript כחלק מ- ECMAScript 2015 (6th Edition, ECMA-262), אנחנו נתייחס לlet במאמר הזה, אך כל הדברים פה חלים גם על const. ההבדל בין const ל let, שעבור const לא ניתן להצהיר שוב על אותו המשתנה.

נושאים 

  • let vs var – הגדרות כלליות
  • הקשר בין let ו Default parameters.
  • Temporal Dead Zone -חברים, לא זה לא סרט אימה! 🙂

הגדרות כלליות

פונקציה ובלוק – Function / Block Scope

ההבדל הגדול והמוכר קשור ל scoping. שזה אומר בעברית פשוטה. var נכנס לסקופ של הפונקציה שעוטפת אותו (נשמר כמשתנה מקומי לפונקציה שעוטפת אותו), לעומת let שנצמד לסקופ של הבלוק הקרוב אליו ( חלק קוד שעטוף בסוגריים מסולסלים), כמובן שאתן דוגמא למשפט חלל הזה.

אז כמו שאמרנו במשפט הראשון var נכנס כמשתנה מקומי לפנוקציה שעוטפת אותו, לכן בסביבה הגלובלית a שווה ערך ל 1. אפילו שבפונקציה b הצהרנו על המשתנה a בפעם השניה הוא כבר שייך למשתנה מקומי של הפונקציה ואין לו השפעה על המשתנה הגובלי. במקרה הזה let ו var יתנהגו באופן זהה.

עכשיו נתייחס לחלק השני, block scope ( קוד שעטוף בסוגריים מסולסלים).

פה אפשר לראות את ההבדל כאשר לא מדובר בפונקציה עוטפת אלא בblock זה יכול להיות for-loop/if-statment/switch-case וכל דבר שעוטף קוד בסוגריים מסולסלים. בעצם במקרה הראשון המשתנה a נמצא רק בסביבה הגלובלית ולכן בתוך ה if אין השפעה על הסביבה והוא דורס את המשתנה a. לעומת זאת כאשר מדובר ב let הוא מתייחס לכל block כסביבת משתנים והוא לא דורס את המשתנה b הגלובלי.

הסביבה הגלובלית – Global

גם פה יש הבדל קטן בין let ו var. משתנה שמצהירים עליו באמצעות var בסביבה הגלובלית נכנס לאובייקט הגלובלי ( window )  בשונה מ let שאינו נכנס ל משתנה הגלובלי ונשאר רק כמשתנה מקומי בהרצה הגלובלית. כמובן שדוגמא לא תזיק.

הצהרה מחדש – Redeclaration

זה די פשוט, כשאתה מתיחחס לvar תצהיר כפי יכולתך (בצחוק כן?!) דוגמא תסביר פה הכל אחסוך במילים.

Default parameters

ערך ברירת מחדל למשתנה, Default parameters, זה נושא בפני עצמו. אבל יש לו קשר מאוד חזק לכל הנושא של TDZ, הוא בעצמו הגיע כחלק מES6, וגם כאן הרבה מהחוקים שהוזכרו למעלה חלים עליו, מיד אסביר. ב ES5 אנחנו יודעים שפרמטרים הם חלק מהמשתנים המקומיים של הפונקציה. בES6 ההגדרה קצת שונה, עבור הפרמטרים של הפונקציה יש שכבת scope נוספת, למה? אחת הסיבות זה כדי למנוע דריסה של closures בזמן אתחול פרמטר בערך דיפולטי לבין משתנים באותו השם בגוף הפונקציה, מה?! … אני יודע, דוגמא! :).

בעצם שכבת הפרמטרים עדיין מסתכלת החוצה במורד ה scope chain ולא מתייחסת למשתנים המקומיים. לכן הפונקציה y מחזירה 4. אבל זה עדיין לא מוכיח שיש scope רק עבור הפרמטרים. אז ….. (תופים)

טוב, זה עדיין לא ברור, נכון המשתנה בתוך הפונקציה לא מעניין כי הוא הסביבה המקומית של הפונקציה, אבל אמרנו שיש סקופ לפרמטרים ובדוגמא למעלה ראינו שהוא לא מוצא בסביבה שלו הוא עולה למעלה ומבקשה את המשתנה במורד ה scop chain. אז למה זה אומר שהוא לא מכיר את x כרגע?! ופה מגיע החלק של הכוכב הראשי בהצגה… Temporal Dead Zone.

Temporal Dead Zone 

אז מי אתה TDZ?  נתחיל בהבנה ש- JavaScript עובר על הקוד פעמיים, בשני שלבים( what? אני לא עובד עליכם ), פעם אחת Creation Phase ופעם שניה Execution Phase, לא אכנס לעומק הדברים. אבל אתם בטח מכירים את אותו השחקן בשם המוכר שלו hoisting. למי שאיבד אותי, מה שזה אומר … דוגמא

בעצם בריצה הראשונה המנוע עובר על הקוד ומקצה מקומות בזכרון, כחלק מזה הוא עובר על var a ושומר מקום בזכרון ל a, רק שפה נכנס עוד שחקן initilzier שאוטומטית מכניס ערך undefined למשתנה. זה אומר שהמקום בזכרון מוקצה אבל הערך בו הוא כרגע undefined. נגמרו ההקצאות ועוברים לשלב השני, הפעלה. בשלב זה הוא מתחיל להריץ את console.log ולכן בלשב זה a קיים אך הוא שווה ל undefined לאחר מכן a = 2 זוהי הפעלה ולכן בזכרון a מצביע על המספר 2, פעולה אחרונה console.log תציג את המספר 2.

אז ב let/const ועוד כמה שחקנים ב ES6 נכנס ההגדרה של TDZ זה אומר שהמנוע בשלב הראשון רץ על המשתנים אבל הפעם הוא מקצה מקום בזכרון ושם אותם במצב שאי אפשר לגשת אליהם עד שלב ההשמה. בשונה מהרבה אנשים שיגידו לכם ש let/const לא מבצעים hoisting (טעות!).

דוגמא? בבקשה

נחזור לדוגמא של הפרמטרים למעלה:

אז בעצם בהגדרה סדר ההשמה של פרמטרים בערך דיפולטי הוא משמאל לימין, לכן עכשיו שאנחנו יודעים על TDZ אפשר להבין שלא הגיוני שנעשה השמה של y=x לפני ההשמה של x. ובגלל שזה שכבת scope נוספת הוא לא משתמש במשתנה x הגלובלי ומבין ש x קיים אבל הוא במצב של TDZ.

ידוע ש Let vs Var זו שאלה מראיון עבודה, אז אני בטוח שהידע הזה יספיק לכם לגרום למראיין לחייך 🙂 בהצלחה חברים.

זמין לשאלות בטוייטר – @lidoravitan :).

המשיכו לעקוב, בקרוב אפרסם מאמר על Open Source, ואיך דחפתי קוד לRepo של React. 🙂

לידור אביטן

מפתח FullStack בחברת Intel-Security

1 comment

Follow

Get every new post delivered to your Inbox

Join other followers