Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get Getter Function in Javascript

Tags:

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.

like image 324
Van Coding Avatar asked Jan 27 '11 22:01

Van Coding


1 Answers

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)
like image 89
zzzzBov Avatar answered Sep 30 '22 19:09

zzzzBov