Javascript对象描述符

时间:2014-10-14 18:25:48

标签: javascript

是否可以在Javascript对象上使用getter / setter,如以下基本功能模型?

function Descriptor(x) {
     this._value = x;

     this.setter = function(x) {
          // Set internal value after some action or modification
          this._value = x + 1;
     }

     this.getter = function() {
          // Return the internal value
          return this._value;
     }
}

var obj = {};

obj.a = new Descriptor();
obj.a = 5;  // Would run the setter defined in the Descriptor object
obj.a == 6; // Should evaluate to true in this trivial example

// Same as above, just an example of being able to easily reuse the getter/setter
obj.b = new Descriptor();
obj.b = 10;  
obj.b == 11;

最终,它应该与类定义中设置的Python描述符类似地操作。我能找到的唯一可以实现这一目标的东西要求在上面的obj创建期间连接getter / setter,并且不能在多个属性或对象上轻松重用。

3 个答案:

答案 0 :(得分:2)

您可以尝试ES5 Object.defineProperty

function addDescriptor(obj, prop) {
    var value = 0;
    Object.defineProperty(obj, prop, {
        get: function(x) {
            return value;
        },
        set: function(x) {
            value = x + 1;
        }
    });
}

var obj = {};

addDescriptor(obj, 'a');
obj.a = 5;
obj.a == 6; // true

addDescriptor(obj, 'b');
obj.b = 10;
obj.b == 11; // true

答案 1 :(得分:0)

我不知道你的环境是什么(它只是标记的javascript),但ES6代理提供了这种get / set的灵活性

复制from MDN

var handler = {
    get: function(target, name){
        return name in target?
            target[name] :
            37;
    }
};

var p = new Proxy({}, handler);
p.a = 1;
p.b = undefined;

console.log(p.a, p.b); // 1, undefined
console.log('c' in p, p.c); // false, 37

答案 2 :(得分:0)

您可以使用Object.defineProperty来定义getter和setter,也可以只使用object initialiser

var obj = {
    value: 0,
    get a(){
        return this.value;
    },
    set a(x){
        this.value = x + 1;
    }
};

我相信你正在尝试这样做:(另一种做Oriol在答案中所做的事情。)

Object.prototype.Descriptor = function(name){
    var value = 0;
    Object.defineProperty(this, name, {
        get: function(){ return value; },
        set: function(x){ value = x + 1; }
    });
};

var obj = {};
obj.Descriptor("a");
obj.Descriptor("b");

obj.a = 5;
obj.b = 10;

obj.a             //6
obj.b             //11

obj.value         //undefined

一切都是分开的,这样可以重复使用函数,同时保持值与所有其他对象的值分开。