2

How to declare read-only static properties in Javascript Class? I'm trying to declare read-only static properties inside javascript class, not able to figure out how to do it.. PLEH Any solution besides Object.defineProperty(obj, prop, descriptor)

Something like this...

class KeyHandler  {
static readonly  KEYS = {
        DIRECTOR: 'director',
        VISION: 'vision',
        ABOUT: 'about',
    }
}

2 Answers 2

7

While available in TS, there's no readonly modifier in JS (at least in June, 2021). There's a long discussion about it, but unless I miss something, it didn't result in anything yet.

You can prevent rewriting the property with getter functions (shown in other answers), but it seems you're more interested in preventing accidental modification of the value object instead. If so, one option available now is using Object.freeze to emulate readonly:

class KeyHandler {
   static KEYS = Object.freeze({
     DIRECTOR: 'director',
     VISION: 'vision',
     ABOUT: 'about',
   })
}

Quoting the docs:

A frozen object can no longer be changed; freezing an object prevents new properties from being added to it, existing properties from being removed, prevents changing the enumerability, configurability, or writability of existing properties, and prevents the values of existing properties from being changed. In addition, freezing an object also prevents its prototype from being changed.

After that, any attempt to modify KeyHandler.KEYS innards will throw in strict mode. This doesn't block attempts to reassign this property though: this...

KeyHandler.KEYS = `Now I'm changed!`

... still works. To disallow this behaviour too, you'll have to combine:

const KEYS = Object.freeze({
  DIRECTOR: 'director',
  VISION: 'vision',
  ABOUT: 'about',
});

class KeyHandler {
   static get KEYS() { return KEYS }
}

Now attempt to rewrite the property will throw in strict mode, too:

TypeError: Cannot set property KEYS of class KeyHandler {
  static get KEYS() { return KEYS } 
} which has only a getter
Sign up to request clarification or add additional context in comments.

Comments

0

You could use a getter for the static property - attempt to write to it errored in Firefox and Web-kit when tested. For reasons unknown, writing to the getter property doesn't error when running the code snippet below on Stack Overflow, even though writing to the property didn't succeed.

class A {
  static get say() {
    return function say() {
      console.log( "this of say function is: %s", this.name);
    }
  }
}

A.say()
A.say = "hello";
console.log(A);

3 Comments

It's the same (minor) issue with the other (now deleted) answer: each call to A.say will create a new object (function in this case). The code doesn't throw because strict mode is not enabled.
@raina77ow - thanks for the reason - I never test code in sloppy mode so got the error immediately. To avoid returning new objects (including functions), one could make the getter return a value held outside the class declaration (under a const binding for example) that is not in scope of the class user - easy enough to do with modules or even an IIFE surrounding the class declaration.
Sure, but here lies the problem: if it's a new object, modifying it won't matter, but if it's one held outside, now you've got the can open. :) That's why I ended up combining those approaches in my answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.