skip to Main Content

Having an object that is made from a class definition:

class Something {
   get prop() {
      ...
   }
}

const s = new Something();

How to detect in code that s.prop is read-only property and cannot be set (and without trying to set it)? What I’ve already tried is to use Reflect.getOwnPropertyDescriptor but it returns undefined in this case.

2

Answers


  1. Stolen and adapted from https://stackoverflow.com/a/70250484/13111630, but you can use these functions to find all the setters and getters for your class.

    function listGetters (instance) {
      return Object.entries(
        Object.getOwnPropertyDescriptors(
          Reflect.getPrototypeOf(instance)
        )
      )
      .filter(e => typeof e[1].get === 'function' && e[0] !== '__proto__')
      .map(e => e[0]);
    }
    
    function listSetters(instance) {
        return Object.entries(
        Object.getOwnPropertyDescriptors(
          Reflect.getPrototypeOf(instance)
        )
      )
      .filter(e => typeof e[1].set === 'function' && e[0] !== '__proto__')
      .map(e => e[0]);
    }

    In your example, you can run listSetters on your Something instance to see that there’s a prop getter but no prop setter.

    class Something {
      get prop() {
        return "foo"
      }
    }
    
    const s = new Something();
    
    
    function listGetters(instance) {
      return Object.entries(
          Object.getOwnPropertyDescriptors(
            Reflect.getPrototypeOf(instance)
          )
        )
        .filter(e => typeof e[1].get === 'function' && e[0] !== '__proto__')
        .map(e => e[0]);
    }
    
    function listSetters(instance) {
      return Object.entries(
          Object.getOwnPropertyDescriptors(
            Reflect.getPrototypeOf(instance)
          )
        )
        .filter(e => typeof e[1].set === 'function' && e[0] !== '__proto__')
        .map(e => e[0]);
    }
    
    console.log(listGetters(s));
    console.log(listSetters(s));
    Login or Signup to reply.
  2. Try this:

    function isPropertyWritable(object, property) {
        if (!(property in object))
            throw new Error('Property not in object');
    
        let descriptor = Reflect.getOwnPropertyDescriptor(object, property);
        if (!descriptor) {
            let prototype = Reflect.getPrototypeOf(object);
            while (prototype) {
                descriptor = Reflect.getOwnPropertyDescriptor(prototype, property);
                if (descriptor)
                    break;
                prototype = Reflect.getPrototypeOf(prototype);
            }
        }
    
        return 'writable' in descriptor ? descriptor.writable : descriptor.set != null;
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search