Reputation: 51861
I just stumbled upon Object.freeze() function. It seems to be a pretty good feature but how to make whole object (including nested objects) immutable?
For example I can change innerProp
here:
const obj = { prop: { innerProp: 1 } };
obj.prop.innerProp = 5;
console.log(obj.prop.innerProp); // 5
Is it possible do freeze nested objects too? (ECMAScript 5/6)
Upvotes: 27
Views: 15741
Reputation: 914
function deepFreeze (o) {
Object.freeze(o);
if (o === undefined) {
return o;
}
Object.getOwnPropertyNames(o).forEach(function (prop) {
if (o[prop] !== null
&& (typeof o[prop] === "object" || typeof o[prop] === "function")
&& !Object.isFrozen(o[prop])) {
deepFreeze(o[prop]);
}
});
return o;
};
https://www.npmjs.com/package/deep-freeze
It's public domain so you don't have to give credit :D
Upvotes: 30
Reputation: 11
One can freeze an object using recursive approach.
const deepFreeze = (param) => {
Object.keys(param).forEach((val) => {
if(typeof param[val] === "object"){
deepFreeze(param[val]);
}
});
return Object.freeze(param);
}
const obj = {
name: "Vidhi",
position: "Software Developer",
travelling: {
europe:"Rome",
asia:"Tokyo",
},
}
deepFreeze(obj);
obj.travelling.asia = "New York"; // cannot assign to read only property "asia" of obj
console.log(obj)
One can see in console that object's value has not changed and it will give error if we use strict mode in javascript.
Upvotes: -1
Reputation: 739
import { readonly } from 'vue/reactive'
let obj = { x: 1 }
obj = readonly(obj)
This will create a readonly proxy on the object and changes will have no effect. You can use the reference as a usual object.
You can use only reactive part of the vue 3, it's small import actually, but has lots of useful functionality
Upvotes: -3
Reputation: 2279
The function can be made much more terse in TS and ES2015.
import type { ReadonlyDeep } from 'type-fest';
export function deepFreeze<T>(o: T) {
Object.values(o).forEach(v => Object.isFrozen(v) || deepFreeze(v));
return Object.freeze(o) as ReadonlyDeep<T>;
}
Upvotes: 5
Reputation: 19
const obj = { prop: { innerProp: 1 } };
Object.freeze(obj);
for(let key in obj) {
if(obj.hasOwnProperty(key) && typeof obj[key] === 'object') {
Object.freeze(obj[key]);
}
}
obj.prop.innerProp = 5;
console.log(obj); // const obj = { prop: { innerProp: 1 } };
Upvotes: -1