במדריך הבא נסקור את ההבדלים שבין let ל-var בשפת java script, על ידי שימוש
בדוגמאות וקטעי קוד.
מאז ששוחררה מהדורת ECMAScript 6 בשנת 2015 חלה מהפכה בשפת JavaScript.מהפכה זו הביאה עימה תוספות
של סינטקס חדש ואפשרויות חדשות לשפה. אחד מן השינויים שהביאה עימה מהדורה זו, היא הדרך שבה מצהירים על משתנה.
עד כה הצהרנו על משתנה באמצעות המילה השמורה var ומעתה ואילך ניתן להצהיר על משתנה באמצעות המילה השמורה let.
אם כן מה ההבדל בין השניים? במי כדאי להשתמש? ועם מי נצהיר על משתנה?
כל זאת ועוד במדריך הבא.
ישנם 3 הבדלים עיקריים בין var לlet:
Redeclare variables
ההבדל הראשון הוא שניתן להצהיר פעם אחת בלבד על משתנה של let
לעומת משתנה של var שעליו ניתן להצהיר מספר פעמים . שימו לב ל-Code Snippet הבא:
let x = 5; //some lines of code let x= 6;//Error var y=5; //some lines of code var y=6;//OK
ניתן לראות בבירור חיסרון גדול להצהרת משתנה באמצעות var, נראה שלא סתם נולד הצורך להצהרת משתנה על ידי let.
תארו לכם שיש לכם קובץ עמוס בשורות של קוד. נתתם שם למשתנה לדוגמא lives שמציין מספר פסילות של שחקן במשחק.
ולאחר מכן שכחתם שנתתם את השם הזה ונתתם אותו בשנית למשתנה אחר-במקום שהמשתנה יידרס ויעלו שגיאות בקוד,
תקפוץ לנו שגיאה שתזכיר לנו שאיננו יכולים להצהיר על משתנה כזה בשנית וכך הקוד יישמר.
לעומת זאת, var ידרוס את אותו המשתנה ויערוך בו את השינוי העדכני שאליו הוצהר,
וכך במקרה שלנו מס' הפסילות של השחקן עלולות להשתנות במערכת ואף ניתן לשנות את הקוד כך שהשחקן
לא יפסל כלל !
scope
ההבדל השני הוא הscope שבו משתני var ו let מוגדרים.
על מנת להבין את ההבדל השני נסביר מהו הscope.
scope– טווח החיים של משתנה או במילים אחרות, שורות הקוד שבהן הוא מוגדר וניתן להשתמש בו.
ב-let הסקופ מתחיל מרגע שהגדרנו עליו ועד סיום הבלוק סוגר מסולסל "{" שבו הוגדר.
לדוגמא:
function func(){ let x=5;//משורה זו מתחיל הסקופ עד לסיום הבלוק שבו הוגדר x++; console.log(x); }//מאחר שהמשתנה הוגדר בבלוק של הפונקציה. כשיסתיים הבלוק המשתנה לא יוגדר. console.log(x);//Error
מה יקרה אם המשתנה מוצהר בבלוק שבתוך בלוק, באיזה מהם יוכר?
ובכן , זה תלוי באיזה בלוק הוצהר,
שהרי הוא יהיה מוכר מהרגע שהוצהר ועד לסיום הבלוק שבו הוצהר וזאת נראה בדוגמא הבאה:
//function scope function func() { let x = 5; //כאן מתחיל הסקופ-טווח החיים של המשתנה if (true) { x++; } console.log(x);//OK }//כאן הסקופ נגמר-סיום הבלוק שבו מוצהר //block-scope function func2() { if (true) { let x = 5; //כאן מתחיל הסקופ של המשתנה מהשורה שבה הוצהר x++; }//כאן הסקופ נגמר-סיום הבלוק שבו מוצהר console.log(x); //Error } //מאחר שהמשתנה הוגדר בבלוק של הפונקציה. כשיסתיים הבלוק גם "חייו" של המשתנה יסתיימו והוא לא יוכר מחוצה לה
אז כפי שכבר הזכרנו-משתנה let מוגדר אך ורק מהרגע שהצהרנו עליו ועד שמסתיים הבלוק שבו הוא הוגדר.
לאחר מכן לא יהיה ניתן להשתמש בו ולכן נקרא גם block-scoped – חי רק בתוך הבלוק שבו הוא הוצהר.
לעומתו, var יכול לחיות גם בבלוק שלא הוצהר.
var נקרא גם function-scoped משום שהוא מוגדר מהרגע שהצהרנו עליו ועד לסיום הפונקציה שבה הוא מוצהר.
גם אם יוצהר בתוך בלוק פנימי הוא יוכר לאורך כל הפונקציה כולה. לדוגמא:
//var- function scope function func(){ var x=5;//כאן מתחיל הסקופ-טווח החיים של המשתנה if(true){ x++; } console.log(x); }//כאן הסקופ יסתיים משום שהוא מסתיים בסוגר של הפונקציה function func2(){ if(true){ var x=5;//כאן מתחיל הסקופ של המשתנה מהשורה שבה הוצהר x++; } console.log(x);//OK }//כאן הסקופ יסתיים משום שהוא מסתיים בסוגר של הפונקציה
זוכרים שאמרנו שאי אפשר להצהיר פעמיים על משתנה של let?
ובכן זה רק באותו הscope!
לאחר הscope התוכנית לא מכירה בו ולכן במקרה של בלוק בתוך בלוק נוכל להצהיר פעמיים על משתנה של let .
ניתן לראות זאת בדוגמא הבאה:
function func3(){ if(true){ let x=5; x++; console.log(x);//5 } let x=6; console.log(x);//6 }
לסיכום-
var- מוכר מרגע שהוצהר ועד לסיום הבלוק של הפונקציה שבה נמצא(וזאת במידה ונמצא בתוך פונקציה).
אך אם הוא נמצא מחוץ לבלוק כנראה שהוא נמצא מחוץ לכל פונקציה כלומר, בתוכנית של Java script עצמה,
ולכן במקרה זה ייקרא global scope.
כלומר יהיה זמין לשימוש מרגע שהוצהר ועד סוף התוכנית).
let- מוכר מרגע שהוצהר ועד לסיום הבלוק שבו הוצהר. (בלוק של פונקציה או של if וכו').
ולהבדל השלישי והאחרון ! נצטרך להכיר מושג שנקרא Hositing
Hoisting
Hoisting -אחת מהתכונות של js היא hoisting .התכונה הזאת קיימת בעוד שפות,
מה שזה אומר שגם אם הכרזנו על משתנה בסוף הקוד הוא יוכר בתחילת הקוד
אך ללא הערך שמוצב בתוכו ולכן הוא רק יוכר וערכו יהיה undefined לדוגמא:
function myFunc() { console.log(x); //undefined var x = 5; } // because of the hoisting -looks like this function myFunc() { var x = undefined; // כלומר המשתנה הוא מוכר אך עוד לא ידוע מה יש בתוכו ולכן אינו מוגדר console.log(x); x=5; }
hoisting נעשה במשתנה של var אך לא במשתנה של let שבו ישר תופיע שגיאה כדוגמא הבאה:
function myFunc(){ console.log(x); let x=5;//כאן הסקופ מתחיל מרגע שהצהרנו על המשתנה }//כאן נגמר הסקופ-סיום הבלוק שבו הוצהר. ולכן בשורה הראשונה המשתנה כלל לא מוגדר. ולכן נקבל שגיאה myFunc();//Error- Uncaught ReferenceError: Cannot access 'x' before initialization
ולסיום תוכלו לראות בתמונה הבאה את ההבדלים שדיברנו עליהם:
Let vs Var
לסיום, ניתן לראות בבירור שעדיף להשתמש בlet על פני var.