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

הקפאת אובייקט בג'אווהסקריפט

רן בר-זיק אפריל 28, 2019 7:07 am 3 תגובות

Freeze & Seal בג'אווהסקריפט ואיך הם עוצרים במוטציה על ידי רפרס

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

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

const object1 = {
  property1: 42
};
const object2 = object1;
object2.property1 = 33;
console.log(object1.property1); // 33 

זה באמת עלול להבעית קצת. אבל ככה השפה עובדת. מצד שני, זה עלול להעיק. פתרון אחד ספציפי הוא תמיד לבצע deep clone (העתקה) או assign כדי לבצע העתקה של האובייקט החדש והמשך עבודה.

const object1 = {
  property1: 42
};
const object2 = Object.assign({}, object1);
object2.property1 = 33;
console.log(object1.property1); // 42 

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

const object1 = {
  property1: 42
};
Object.freeze(object1)
const object2 = object1;
object2.property1 = 33;
console.log(object1.property1); // 42 
console.log(Object.isFrozen(object1)); // true

מה שה-freeze עושה הוא בעצם הקפאת כל התכונות המיידיות של האובייקט. אפשר לבדוק אם אובייקט קפוא באמצעות isFrozen. כדאי לשים לב שאם מדובר באובייקט מורכב (כלומר אובייקט שהתכונה שלו היא אובייקט אחר) – יהיה אפשר לבצע שינוי של האובייקט. בדיוק כמו ב-const.

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


const myArray = ['Value', 'Value2', 'Value3'];

Object.freeze(myArray);

function muteMeBaby(someArray) {
  someArray[0] = 'newValue';
  return someArray;
}

const newArray = muteMeBaby(myArray);
console.log(newArray); // ["newValue", "Value2", "Value3"]
console.log(myArray); // ["newValue", "Value2", "Value3"]

ניסיון של שינוי אובייקט שנמצא ב-freeze יניב שגיאה אם אנו נמצאים ב strict mode.

האמת היא שלא יצא לי לראות יותר מדי שימושים ב-freeze, ולפי דעתי זו טכניקה שאני לא הייתי שמח לראות אותה בקוד שלי מכמה סיבות. אבל ללא ספק טוב לראות וטוב להכיר.

דרך מעניינת נוספת לקבע אובייקטים היא seal. לא, אין הכוונה לזמר האיכותי (האיכותי!) משנות ה-90 אלא לטכניקה שבאמצעותה אני יכול לקבע את התכונות של האובייקט אבל לאפשר לשנות את הערך שלהן.

אני חושב שבמקרה הזה דוגמה טובה יותר מאלף מילים. יצרתי אובייקט ועשיתי לו seal. מהרגע הזה, אני יכול לשנות את התכונות שלו אבל אני לא יכול להוסיף לו חדשות.

const object1 = {
  property1: 42
};
Object.seal(object1)
const object2 = object1;
object2.property1 = 33;
object2.property2 = 11;
console.log(object1.property1); // 33
console.log(object1.property2); // undefined
console.log(Object.isSealed(object1)); // true
console.log(object2.property2); // undefined

See the Pen Seal baby seal by Ran Bar-Zik (@barzik) on CodePen.

זה כמובן עובר לכל האובייקטים שיש להם רפרפנס אליו. זה לא עוצר את כל המוטציות אבל בהחלט יכול לאכוף ממשק. ושוב, זה נחמד מאוד להכיר – אבל אני לא חושב שיש לזה הרבה שימוש. בתכנות מונחה עצמים, הרבה פעמים אנו כן רוצים להתחייב לממשק מסוים. אבל ג'אווהסקריפט היא prototype based וניסיון להכניס לתוכה את ההגיון של ה-class יכול להיות בעייתי. כאמור טוב להכיר, שימושי בכמה מקרים – באופן אישי לא ראיתי שימוש מאוד נרחב.

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

3 תגובות

  1. אלעד כהן הגב אפריל 30, 2019 בשעה 8:24 am

    אחד השימושים הנחמדים שראיתי – הקפאת אובייקט שלא משתנה כדי לחסום את בדיקת הריאקטיביות של Vue.js ולשפר ביצועים באופן משמעותי, כפי שמופיע כאן:
    https://vuedose.tips/tips/improve-performance-on-large-lists-in-vue-js

    וכמובן תודה על עוד מאמר כיפי ומהנה

  2. עידן דוידי הגב אפריל 30, 2019 בשעה 10:22 pm

    לא הכרתי את הפונקציה הזאת ונהנתי מאוד מהקריאה.

    יש לך טעות קטנה בדוגמא עם המערך המוקפא. הפלט יהיה "Value" ולא "newValue" עבור התא הראשון בכל אחד מהמערכים

    https://i.imgur.com/QUr8PEg.png

  3. מאיר הגב מאי 1, 2019 בשעה 9:50 pm

    מאמר מעולה כתמיד

    כמה נקודות חשובות

    deep clone !== assign
    בשביל לבצע העתקה של אובייקט ב-js באמצעות assign
    נדרש לבצע deep assign אחרת זה יעתיק גם הרפרנס
    שינוי של ערך באובייקט פנימי במועתק יגרור שינוי גם במקורי

    בנוסף Object.freeze יקפיא לו רק את המקורי אלא גם את המועתק
    ואמנם שינוי באחד לא ישפיע על השני אך גם לא על עצמו

השארת תגובה

ביטול

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

ללמוד לתכנת ג'אווהסקריפט בעברית שגייס יותר משלוש מאות אלף שקל ולמעלה מ-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 | הצהרת הנגישות של האתר | אבטחת מידע ודיווח על בעיית אבטחת מידע

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