const vs Object.freeze

חיים טי
Web developer
חיים טי
Web developer
כבר מזמן אף אחד לא משתמש ב var על מנת ליצור משתנים ב js.
ה"דקלרציות" (הַצהָרָות) const ו let ביססו היטב את מקומן, ואין אף לא ג'וניור אחד שיגיע לראיון עבודה בלי שהוא יודע היטב את ההבדלים בין השלוש.
 
יחד עם זאת, למרות שהדקלרציה const מונעת מאיתנו לשנות את הערך של המשתנה שיצרנו, ישנם תרחישים שההגנה הזו לא מספיק טובה, ואנו נדרשים להוסיף הגנות נוספות.
למשל אם יצרנו אובייקט, גם אם השתמשנו ב const, בכל זאת נוכל לשנות את הערכים של המאפיינים הפנימיים של האובייקט (properties).
 
				
					const obj = {
    color: "red",
    width: "20",
}

obj.color = "blue"; // this will work!
console.log(obj.color) // = "blue"
				
			
וכאן מגיעות שלוש מתודות שאפשר להשתמש בהן: 
freeze
seal
preventExtension

Freeze

מתודת freeze כשמה כן היא, מקפיאה את האובייקט ואת המאפיינים שלו כך שלא ניתן לשנות את ערך המאפיינים הקיימים או למחוק אותם, וגם לא ניתן להוסיף מאפיינים חדשים.
אם ננסה להוסיף, לשנות, או למחוק אחד מהמאפיינים של האובייקט זה פשווט לא יעבוד.
דוגמא:
				
					const obj = {
    color: "red",
    width: "20",
}

Object.freeze(obj);

obj.color = "blue"; // this wont work!
console.log(obj.color) // = "red"
				
			
אבל כאן עוד לא סיימנו להגן על האובייקט שלנו (ועל עצמנו בעצם) מפני שינויים.
מתודת freeze מקפיאה רק שכבה אחת לעומק. ז"א שכל  המגבלות שfreeze נותנת לנו פועלות רק על האובייקט עצמו ועל שכבה אחת של מאפיינים. 
אבל אם אחד המאפיינים של האובייקט הוא אובייקט בפני עצמו וגם לו יש מאפיינים, הפעלת freeze על אובייקט ה"אב" לא תשפיע על המאפיינים של אובייקט ה"בן" ואנחנו נוכל לשנות את הערכים של המאפיינים של אובייקט ה"בן".   
				
					// Although the "freeze" we can change inner properties.
const obj = {
    color: "red",
    price: {
        onSale: 50,
        regular: 100,
    }
}

Object.freeze(obj);

obj.price.onSale = 30; // this will work!
console.log(obj.price.onSale) // = 30



				
			
כדי להקפיא את האובייקט בשלמותו כולל כל ה-"ילדים" שיש לו, יש להפעיל את מתודת freeze על כל אחד מה-"ילדים" של האובייקט: 
				
					const obj = {
    prop1: {
        prop2: {
            prop3: {
                prop4: {
                    regular: 100,
                }
            }
        }

    }
}

// this is a recursive function to freeze an object and all it's children to the bone! 
function freezeObject(obj){
    Object.keys(obj).forEach(key => {
        if (obj[key] instanceof Object){
            obj[key] = freezeObject(obj[key]);
        }
    })
    return Object.freeze(obj);
}

const frozen = freezeObject(obj)
frozen.prop1.prop2.prop3.prop4.regular = 50; //won't work!
console.log(frozen.prop1.prop2.prop3.prop4.regular) // = 100

				
			

seal

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

				
					const obj = {
    color: "red",
    width: 20,
}

Object.seal(obj);

obj.color = "green"; // will work!
delete obj.width; // won't work!
obj.height = 20; // won't work!
				
			

כמו freeze, גם seal משפיעה רק על שכבה אחת לעומק, וכדי להחיל אותה על כל האובייקט, עם כל שכבותיו יש להפעיל אותה על כל אחד מה "ילדים" של האובייקט.

preventExtension

מתודת preventExtension מגבילה עוד פחות מהמתודה הקודמת, seal. היא מאפשרת לשנות את ערכי המאפיינים הקיימים של האובייקט, ומאפשרת גם למחוק מאפיינים.
הדבר היחיד ש preventExtension מונעת מאיתנו הוא להוסיף לאובייקט מאפיינים חדשים.
 
* חשוב! גם אם לאובייקט היה מאפיין מסויים ואנחנו מחקנו את המאפיין אחרי שהפעלנו את מתודת preventExtension, לא נוכל ליצור את המאפיין הזה מחדש.
				
					const obj = {
    color: "red",
    width: 20,
}

Object.preventExtension(obj);

obj.color = "green"; // will work!
delete obj.width; // will work!
obj.height = 20; // won't work!
				
			
כמו freeze, ו-seal, גם preventExtension משפיעה רק על שכבה אחת לעומק, וכדי להפעילה על כל האובייקט על כל שכבותיו יש להפעיל את המתודת על כל אחד מה "ילדים" של האובייקט.
יש שלוש מתודות נוספות שכדאי להכיר אם אתם מתכננים להשתמש ב freeze ובחברותיה:
 
isFrozen – בודקת האם האובייקט עבר הפעלה של freeze.
isSealed – בודקת האם האובייקט עבר הפעלה של seal.
isExtensible – בודקת האם האובייקט עבר הפעלה של preventExtension.
עד כאן בנושא זה, מוזמנים להשאיר הארות והערות, ובקשות לנושאים לפוסטים הבאים!
נגישות