חולמים על קריירה בהייטק?
בדקו את הקורסים שלנו:
משתנים בג'אווה סקריפט - כל מה שצריך לדעת.
במאמר זה נבין את השוני בין שני סוגי משתנים בשפה,כאלו שמוגדרים by value לעומת אלו שמוגדרים by reference.
הכל יוסבר בדוגמאות על מנת לפשט לכם את השוני בצורה הפשוטה ביותר.
תוכן עניינים:
מה הם סוגי המשתנים ועל ההבדלים בניהם?
כאשר כותבים קוד בjavascript עלינו להבין שיש שלושה דרכים להגדיר משתנים let, var ו const.
קיימת גם יצירה של משתנה גלובלי ללא הגדרת כל אחד מהנ״ל לדוגמא:
1
str = “hello world”;
אבל לא נהוג להגדיר כך משתנים, שכן הם יכולים ליצור לנו side effects בקוד שנכתוב ועל כן נמליץ שלא להשתמש בשיטה זאת וגם לא נצלול להסברים מיותרים.
בכל אחד מהדרכים שנבחר בין אם זה let, var או const . חשוב להבין שיש משתנים בשפה שמוגדרים על ידי ערך ממשי וכאלו על ידי הצבעה לכתובת בזיכרון,
לא להיבהל מהמונחים המפוצצים, נבין מיד הכל בפשוטות.
סוגי המשתנים בג'אווה סקריפט:
במאמר זה נדבר על סוגי המשתנים הנפוצים/רלוונטים לבעיה שנציג ולכן לא נדבר על symbol, bigint, null, undefined.
אז אם נתרכז בחמשת המשתנים הראשונים חשוב לזכור בעל פה את הדבר הבא:
איך זה בא לידי ביטוי ביום יום כמתכנתי ג'אווה סקריפט?
אז למה כל זה משנה לנו בכלל? חשוב מאוד להבין את השוני בין סוגי המשתנים ונבין בצורה הפשוטה על פי דוגמאות איך זה יכול להשפיע לנו על הקוד.
חשוב לציין שמאמר זה נשתמש בlet ו const אבל הכל תקף גם כאשר נשתמש בvar, מבלי לצלול כרגע מה ההבדל בניהם . (לינק)
דוגמא 1:
1
2
3
4
5
let x = 10;
let y = x;
x = 50;
console.log(x); // יודפס 50
console.log(y); // יודפס 10
במקרה זה, מאחר שמשתנים מסוג number, הם מוגדרים על פי הערך (by value) ולכן לכל אחד חיים משל עצמו.
מה הכוונה? שכאשר כתבנו let y = x יצרנו משתנה חדש בשם y והעתקנו ממש את הערך של x אל משתנה חדש עם השם y.
במקרה כזה כאשר אנחנו משנים את משתנה המקור x, ומזינים לו ערך חדש, זה לא ישפיע כלל על y.
חשוב להבין שגם עבור משתנים מסוג מחזורות ובוליאנים ההתנהגות תיהיה זהה לחלוטין, שכן הם מוגדרים כמשתנים by value בשפה.
עכשיו נדבר על אובייקטים ומערכים, כאן העניינים קצת מסתבכים.
דוגמא 2:
1
2
3
4
let obj1 = {a: 10};
let obj2 = obj1;
obj1.a = 50;
console.log(obj2.a); // יודפס 50
למה כאן כאשר אנו משנים ערך של מפתח באובייקט obj1 אנחנו רואים שהשינוי חל על obj2,זאת מאחר שאובייקטים בג'אווה סקריפט מוגדרים על פי כתובת - by reference,
מה זה אומר? שהם מוגדרים על פי הצבעה בזכרון, ולכן בשורה השניה כשהגדרנו את obj2 בפועל הערכים הם זהים לא רק בערך כמו במספרים אלא גם ממש מצביעים לאותו
הגדרה בזיכרון, ולכן כאשר משנים את ערך המפתח, כל מי שמצביע על אותו אובייקט ישתנה, כי בפועל הם זהים לחלוטין ומצביעים על בדיוק אותו ערך.
דוגמא 3:
1
2
3
4
const arr = [1,2,3];
const arr2 = arr;
arr[1] = 40;
console.log(arr2[1]); // יודפס 40
גם עבור מערכים, כמו אובייקטים, מדובר בהצבעה בזכרון by reference ולכן כאשר נשנה את המערך הראשון, ערך המערך השני ישתנה מיד בהתאם, כי בפועל הם מצביעים
לאותו מערך שהוגדר.
חשוב לציין שהפעם השתמשנו בconst אבל זה חסר חשיבות, זה עובד בצורה זהה גם עבור let.
דוגמא 4:
1
2
3
4
const arr = [{a: 1}, {b:2}];
const arr2 = arr;
arr[1].b = 10;
console.log(arr2[1].b); // יודפס 10
גם כאן לא במפתיע נוכל לראות שמאחר שמדובר במערך של אובייקטים, ההצבעה בזכרון עבור האיבר במערך הינו אובייקט, ולכן כאשר אנחנו משנים את ערכו של המפתח
באובייקט זה יחול על כל מי שמצביע לאותו אובייקט בזכרון, בין אם זה הגדרת אובייקט כמו בדוגמא 3 או בין אם זה אובייקט בתוך מערך כמו בדוגמא זו.
איפה זה עוד פוגש אותנו ולמה חשוב לשים לב?
כאשר אנחנו מתכנתים בג'אווה סקריפ חשוב שנבין מתי אנחנו מעבירים משתנים עם ערך ממשי (מספר, מחרוזת, בוליאני), ואז ג'אווה סקריפ מעתיק (משכפל) לנו ממש את הערך
למשתנה חדש, ומתי אנחנו מעבירים משתנה עם הצבעה לזכרון (אובייקט, מערך) ואז מדובר באותו משתנה ממש וכל שינוי בו יושפע לאורך כל האפליקציה שלנו.
דוגמא:
1
2
3
4
5
6
let x = 10;
function foo(y){
y = 20;
}
foo(x);
console.log(x); // יודפס 10
במקרה הזה הארגומנט שנשלח לפונקציה מועבר על פי ערך ולכן השפה יוצרת לנו העתקה עמוקה ומשתנה חדש בשם y עם אותו ערך שנשלח אבל x וy מבודדים אחד מן השני
בשני משתנים נפרדים.
ולכן כאשר אנחנו משנים את ערכו בתוך הפונקציה זה לא משפיע על המשתנה שנשלח והוגדר מבחוץ (x).
דוגמא 2:
1
2
3
4
5
let arr = [10, 20, 30];
function foo(arr) {
arr[2] = 80;
}
console.log(arr); // יודפס 10,20,80
במקרה הזה, מאחר שמדובר במערך ויש לנו הצבעה בזכרון, השינוי שהפונקציה תעשה על המערך ישפיע מיידית על תוכנו לאורך כל האפליקציה מאחר שבפועל המשתנה שמוגדר, הינו הצבעה ישירה בזכרון לאותו משתנה.
מה אנו למדים מהמאמר?
בתור מתכנתים בג'אווה סקריפט, אנחנו חייבים להבין ולשלוט בקונספט סוגי המשתנים והתנהגותם.
אם לא נבין זאת, נוכל לגרום לבאגים עצומים בקוד שלנו, שכן משתנים המוצבעים בזכרון, ישפיעו לנו בצורה גורפת על כל הקוד וכל שינוי שנבצע,
כל עוד מדובר במערך או אובייקט, משפיע לאורך כל האפליקציה שנבנה.
אם תרצו להעמיק את הידע שלכם בשפה מוזמנים לקחת את קורס הjavascript המעודכן וללמוד את כל העקרונות ה חשובים של השפה.