Reputation: 24524
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
Reputation: 179046
__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.
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 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
.
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)
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
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
Reputation: 3231
In Google Chrome lookupGetter/lookupSetter is broken: http://code.google.com/p/chromium/issues/detail?id=13175
Upvotes: 1