Search code examples
javascriptsettergettergetter-setter

Get Getter Function in Javascript


In JavaScript there is the possibility to create getters and setters the following way:

function MyClass(){
 var MyField;
 this.__defineGetter__("MyField",function(){
  return MyField;
 });
 this.__defineSetter__("MyField",function(value){
  MyField = value;
 });
}

But is there a way to get the Getter or Setter FUNCTION? I think of something like this:

var obj = new MyClass();
obj.__getSetter__("MyField")("MyValue");

I need such a functionality when extending base classes. For example: Class "A" has field "a", Class "B" extends from "A" and also wants to have a field "a". To pass values from the "a"-field of a "B"-object to the "a"-field of a "A"-object I need to get the setter/getter function before overriding them.


Solution

  • The old way

    __defineGetter and __defineSetter__ have been deprecated in the time since this question was initially posted.

    Accessing those accessor and mutator functions was handled with __lookupGetter__ and __lookupSetter__ respectively.

    Example

    function MyClass() {
     var MyField
     this.__defineGetter__("MyField",function(){
      return MyField
     })
     this.__defineSetter__("MyField",function(value){
      MyField = value
     })
    }
    
    var obj = new MyClass()
    obj.__lookupSetter__("MyField")("MyValue")
    console.log(obj.MyField)

    The new way

    The current standard way to create a dynamic accessor or mutator is to use Object.defineProperty or Object.defineProperties.

    Accessing accessor and mutator functions can be done using Object.getOwnPropertyDescriptor and Object.getOwnPropertyDescriptors.

    Example

    function MyClass() {
     let MyField
     Object.defineProperty(this, 'MyField', {
       get: () => MyField,
       set: value => {
         MyField = value
       }
     })
    }
    
    var obj = new MyClass()
    Object.getOwnPropertyDescriptor(obj, 'MyField').set('MyValue')
    console.log(obj.MyField)

    ES6 Classes

    Note that Object.getOwnPropertyDescriptor works even when using get and set keywords, however there are a couple gotchas if you're using the class keyword.

    Accessors and mutators defined on a class are not "own properties" of the instances of that class. Instead they belong to the prototype for that class (class is just syntactic sugar for declaring a prototype).

    Because the functions added to the class are added to the prototype you will need to be careful about context when calling the getter or setter.

    class MyClass {
      get MyField() {
        return this._myField
      }
      set MyField(value) {
        this._myField = value
      }
    }
    
    const obj = new MyClass()
    Object.getOwnPropertyDescriptor(MyClass.prototype, 'MyField').set.call(obj, 'MyValue')
    console.log(obj.MyField)