Van Coding
Van Coding

Reputation: 24524

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.

Upvotes: 26

Views: 12208

Answers (4)

zzzzBov
zzzzBov

Reputation: 179046

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)

Upvotes: 23

alexpods
alexpods

Reputation: 48477

Actually, __lookupGetter__ and __lookupSetter__ methods are deprecated. Instead of these you must use:

/* __lookupGetter__ */
Object.getOwnPropertyDescriptor(obj, 'MyField').get;

/* __lookupSetter__ */
Object.getOwnPropertyDescriptor(obj, 'MyField').set;

Upvotes: 21

sw.
sw.

Reputation: 3231

In Google Chrome lookupGetter/lookupSetter is broken: http://code.google.com/p/chromium/issues/detail?id=13175

Upvotes: 1

Ken Redler
Ken Redler

Reputation: 23943

Take a look at lookupGetter.

Upvotes: 2

Related Questions