关于setter:使用Javascript获取Getter函数

Get Getter Function in Javascript

在JavaScript中,可以通过以下方式创建getter和setter:

1
2
3
4
5
6
7
8
9
function MyClass(){
 var MyField;
 this.__defineGetter__("MyField",function(){
  return MyField;
 });
 this.__defineSetter__("MyField",function(value){
  MyField = value;
 });
}

但是有没有办法获取Getter或Setter函数?我想到了这样的东西:

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

在扩展基类时,我需要这样的功能。例如:
类" A"具有字段" a",类" B"从" A"扩展,并且还希望具有字段" a"。
要将值从" B "对象的" a "字段传递到" A "对象的" a "字段,我需要在覆盖之前获取setter / getter函数他们。


实际上,不赞成使用__lookupGetter____lookupSetter__方法。除了这些,您必须使用:

1
2
3
4
5
/* __lookupGetter__ */
Object.getOwnPropertyDescriptor(obj, 'MyField').get;

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

旧的方式

自最初发布此问题以来,

__defineGetter__defineSetter__已被弃用。

分别使用__lookupGetter____lookupSetter__处理访问这些访问器和mutator函数。

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
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)

新方法

创建动态访问器或增变器的当前标准方法是使用Object.definePropertyObject.defineProperties

可以使用Object.getOwnPropertyDescriptorObject.getOwnPropertyDescriptors来访问访问器和更改器功能。

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
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类

请注意,即使使用getset关键字,Object.getOwnPropertyDescriptor也可以使用,但是如果您使用class关键字,则有一些陷阱。

class上定义的访问器和变量不是该类实例的"自身属性"。相反,它们属于该类的原型(class只是声明原型的语法糖)。

由于添加到类的函数已添加到原型,因此在调用getter或setter时需要注意上下文。

1
2
3
4
5
6
7
8
9
10
11
12
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)


看看lookupGetter。


在Google Chrome浏览器中,lookupGetter / lookupSetter损坏:http://code.google.com/p/chromium/issues/detail?id=13175