אינטרנט ישראל
  • ראשי
  • אודות רן בר-זיק ואינטרנט ישראל
  • ערוץ טלגרם
  • מסטודון
  • התחברו אלי בטוויטר
  • התחברו אלי בלינקדאין
  • ספר ג'אווהסקריפט
  • ראשי
  • אודות רן בר-זיק ואינטרנט ישראל
  • ערוץ טלגרם
  • מסטודון
  • התחברו אלי בטוויטר
  • התחברו אלי בלינקדאין
  • ספר ג'אווהסקריפט
ראשי » פיתוח אינטרנט » jQuery למתקדמים » JavaScript Hoisting

JavaScript Hoisting

רן בר-זיק פברואר 22, 2015 7:48 am 4 תגובות

אחת התכונות המשמעותיות של JavaScrtipt ששווה להכיר

כדאי תמיד להשאר מעודכנים! אם יש לכם טלגרם, בדקו את ערוץ הטלגרם של האתר שבו אני מעדכן על פוסטים חדשים 🙂 אם אתם רוצים ללמוד תכנות באופן מקיף ומסודר, הצטרפו לאלפי הלומדים בפרויקט "ללמוד ג'אווהסקריפט בעברית" שמלמד לתכנת בג'אווהסקריפט, ב-Node.js ובריאקט וגם מלמד על תרומה לקוד פתוח. גם ספרים דיגיטליים וגם ספרים מודפסים. בשיתוף הקריה האקדמית אונו ובתמיכת חברות מובילות כגון Wix, Outbrain, Elementor, Iron Source, Chegg, Really Good ועוד.

במאמר זה אני אסביר על JavaScript Hoisting – אחת מהתכונות הבסיסיות של JavaScript שכמעט כל מפתח Angular\Node.JS מכיר היטב. מדובר בתכונה מאוד חשובה שהכרות איתה יכולה למנוע מכם למרוט שיערות יקרות מראשכם. עם אלו שחושבים שמדובר בתכונה אלמנטרית – הסליחה.

Hoisting היא בעצם הנטייה של JavaScript להכריז על כל המשתנים בתחילת הבלוק של הקוד. כל המשתנים ב-JavaScript מוגדרים בתחילת הבלוק בלי שום קשר למתי החלטנו להכריז עליהם. נשמע כמו סינית? בואו נסתכל על הקוד הזה:

var myvar = 'hello!!!';
  
(function() {
  alert(myvar);
})();

אנו מכריזים על המשתנה myvar כמשתנה גלובלי. אחר כך יש לנו פונקציה אנונימית (כלומר פונקציה ללא שם) שמריצה את עצמה. למה אנחנו עושים את זה? כדי לממש בלוק של קוד. מה שיש מחוץ לקוד הוא הסקופ הגלובלי. מה שיש בתוך הבלוק של הקוד (כלומר הפונקציה האנונימית) זה הסקופ של הפונקציה האנונימית. ב-JavaScript, הודות ל-closure, כל המשתנים שזמינים בסביבה הגלובלית זמינים גם בסקופ שלנו.

אם תעתיקו ותדביקו את הקוד שנמצא לעיל בקונסולה שלכם, תקבלו מיד alert של hello.

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

על מנת לחדד את העניין, מה דעתכם נקבל אם נריץ את הדבר הבא?

var myvar = 'hello!!!';
  
(function() {
  var myvar = 'World!!!'
  alert(myvar);
})();

alert(myvar);

ה-alert הראשון יהיה World!! כמובן. אבל מה יהיה ה-alert השני? התשובה היא כמובן hello!!! רגע, למה?!? הרי שיניתי את myvar! התשובה היא שלא באמת שיניתי אותו – אלא הגדרתי myvar באמצעות var בסקופ הפנימי של הפונקציה האנונימית. "מבחוץ", כלומר בסקופ הגלובלי, myvar עדיין hello. אם אני רוצה לדרוס את myvar הגלובלי, אני צריך לעשות משהו כזה:

var myvar = 'hello!!!';
  
(function() {
  myvar = 'World!!!'
  alert(myvar);
})();

alert(myvar);

אם אני לא משתמש ב-var, אני בעצם דורס את המשתנה בסקופ הגלובלי ואז שני ה-alerts יהיו world.

עד כאן בנוגע ל-scoping וגם בנוגע ל-closure. אבל מה בנוגע ל-hoisting? זה השוס האמיתי, מה לפי דעתכם יודפס כאן?

var myvar = 'hello!!!';
  
(function() {
  alert(myvar);
  var myvar = 'World!!!'
})();

בואו ונראה: אנו מגדירים את myvar בסקופ הגלובלי ומכניסים לו את ה-hello. נכנסים לסקופ של הפונקציה האנונימית. מה הערך של myvar? עדיין hello. יש לנו alert ורק אחרי ה-alert אנו משנים את ה-myvar. אז די ברור שה-alert יהיה hello.

אבל אם נדביק את הקוד ונריץ אותו בקונסולה, אנו נקבל undefined. למה?!? התשובה היא hosting. בתחילת כל בלוק של קוד, ה-JavaScript אוסף את כל המשתנים שמוגדרים ומכריז עליהם בתחילת הבלוק. כלומר שהקוד שלעיל הוא תמיד משהו כזה:

var myvar;
myvar = 'hello!!!';
  
(function() {
  var myvar;
  alert(myvar);
  myvar = 'World!!!'
})();

כך זה נראה מבחינת ההרצה. ואז די ברור למה אנחנו מקבלים undefined. ברגע שאנחנו בעצם משתמשים ב-var, אנו יוצרים hoisting. קודם JavaScript אוסף את כל המשתנים המוגדרים ב-var ומעביר אותם לראשית הבלוק והם מאוכלסים כאשר הם מאוכלסים. זה, אגב, מניסיון, מטריף כל מתכנת JavaScript שעובר פאזה לקוד יותר משמעותי. בגלל זה, מאוד מקובל תמיד להגדיר את כל המשתנים בתחילת בלוק של קוד. כלומר משהו בסגנון הזה:

(function() {
  var myvar,somevar,anothervar;

})();

אם אתם משתמשים ב-jsLint במוד strict, הוא גם יחייב אתכם לעשות את זה. בכל מקרה מדובר בנוהג שמאוד מסייע להבין את ענייני הסקופינג וה-hoisting.

בגדול, זה יכול להראות לכם מוזר ולא קשור לכלום. במיוחד אם עברתם קצת במחוזות ה-jQuery או ספריות נוספות. אבל מהניסיון שלי שווה להכיר את זה במיוחד אם שוקלים לעבור לספריות JavaScript כמו Node.JS.

כדאי תמיד להשאר מעודכנים! אם יש לכם טלגרם, בדקו את ערוץ הטלגרם של האתר שבו אני מעדכן על פוסטים חדשים 🙂 אם אתם רוצים ללמוד תכנות באופן מקיף ומסודר, הצטרפו לאלפי הלומדים בפרויקט "ללמוד ג'אווהסקריפט בעברית" שמלמד לתכנת בג'אווהסקריפט, ב-Node.js ובריאקט וגם מלמד על תרומה לקוד פתוח. גם ספרים דיגיטליים וגם ספרים מודפסים. בשיתוף הקריה האקדמית אונו ובתמיכת חברות מובילות כגון Wix, Outbrain, Elementor, Iron Source, Chegg, Really Good ועוד.
ג'אווה סקריפט ו-jQuery באתרי אינטרנט

4 תגובות

  1. משתמש אנונימי (לא מזוהה) הגב יוני 28, 2016 בשעה 10:25 am

    חלק הקוד השני אמנם מדגים את הנושא, אבל ההסבר לא באמת ברור.

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

  2. יוליה הגב אפריל 1, 2020 בשעה 12:23 pm

    אגב הפונקציה האנונימית שעטופה בסוגריים היא נקראת IIFE (Immediately Invoked Function Expression) ששווה לציין בכתבה.

  3. אפרים הגב פברואר 10, 2022 בשעה 7:53 pm

    תודה! הסבר טוב פשוט וברור

  4. יוסף הגב נובמבר 3, 2022 בשעה 11:33 am

    לא הודגש שהאמור מתייחס לשימוש ב-var. כאשר מצהירים על המשתנה עם let (או const) אין hoisting בכלל.

השארת תגובה

ביטול

ללמוד ג'אווהסקריפט בעברית

ללמוד לתכנת ג'אווהסקריפט בעברית שגייס יותר משלוש מאות אלף שקל ולמעלה מ-2000 תומכים - בואו ללמוד עכשיו איך לתכנת.

רשימת הנושאים
  • מדריכים
    • ריאקט
    • טייפסקריפט
    • ECMAScript 6
    • ES20XX
    • Node.js
    • Express
    • רספברי פיי
    • Babel
    • docker
    • MongoDB
    • Git
    • לימוד MySQL
    • SASS
    • jQuery
    • CSS3
    • HTML 5
    • SVN
    • LESS
  • פיתוח אינטרנט
    • פתרונות ומאמרים על פיתוח אינטרנט
    • jQuery Scripts
    • jQuery למתקדמים
    • יסודות בתכנות
    • נגישות אינטרנט
  • חדשות אינטרנט
  • מידע כללי על אינטרנט
    • רשת האינטרנט
    • בניית אתרי אינטרנט
  • rss logo

    לכל המאמרים

    לכל המאמרים שפורסמו באינטרנט ישראל משנת 2008 ועד עכשיו.
  • rss logo

    RSS Feed

    משתמשים בקורא RSS? אם כן, עקבו אחרי אינטרנט ישראל באמצעות פיד ה-RSS!
    מה זה RSS?
  • Twitter logo

    עקבו אחרי בטוויטר

    בחשבון הטוויטר שלי אני מפרסם עדכונים מהירים על חדשות בתחום התכנות והיזמות, התרעות על מצבי חירום ורכילות בוערת על תחום הווב.
    מה זה טוויטר?
  • facebook like image

    ערוץ הטלגרם של אינטרנט ישראל

    בערוץ הטלגרם של אינטרנט ישראל אני מפרסם את הפוסטים של באתר וכן עדכונים טכנולוגיים נוספים.
    מה זה טלגרם?
  • github logo

    הפרויקטים שלי בגיטהאב

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

כל הזכויות שמורות לרן בר-זיק ולאינטרנט ישראל | מדיניות הפרטיות של אתר אינטרנט ישראל | אתר אינטרנט ישראל נגיש לפי תקן WCAG 2.0 AA | הצהרת הנגישות של האתר | אבטחת מידע ודיווח על בעיית אבטחת מידע

גלילה לראש העמוד