'Creating an immutable object as a class in javascript

I would like to create an object that has various methods, but the core data can never be changed. If using a class-based approach, are using private variables the only way that this can be done? For example:

class Data {
    #name;
    #elements;
    constructor(name, elements = new Set) {
        this.#name = name;
        this.#elements = elements;
    }
    get name()     { return this.#name };
    get elements() { return this.#elements };
    get size()     { return this.#elements.size };
}
export { Data }; // note: why doesn't export work in StackOverflow's javascript runner?

What can be improved on the above?



Solution 1:[1]

If you want the entire object to be immutable you can call Object.freeze in the constructor.

class Data {
    constructor(name, elements = new Set) {
        this.name = name;
        this.elements = elements;
        Object.freeze(this);
    }
    get size() { return this.elements.size };
}

var obj = new Data('A');

obj.name = 'B'; // Has no effect since the object is frozen.
console.log(obj.name); // Prints 'A'

obj.elements.add(42); // This works since the object is frozen only shallowly.
console.log(obj.size); // Prints 1

Of course, this does not work if you just want some properties to be immutable and others not. Also note that Object.freeze creates a shallow freeze. Therefore new elements can be added to obj.elements in the example above. If you don't want this behavior, you need to call Object.freeze recursively on all properties (see deepFreeze).

The call to Object.freeze may pose problems if another classes inherits from your Data class. See this question for solutions in this scenario.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1