28

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.

2
  • I would advice against relying on that non-standard syntax. Commented Jan 27, 2011 at 23:04
  • you can add the answer as an answer and select it since you found it for yourself Commented Jan 27, 2011 at 23:05

4 Answers 4

24

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)

Sign up to request clarification or add additional context in comments.

Comments

21

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;

Comments

2

Take a look at lookupGetter.

Comments

1

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

Comments

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.