简体   繁体   中英

Javascript object descriptors

Is it possible to use getters/setters on Javascript objects like the following basic functionality mockup?

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;

Ultimately, it should operate similarly to a Python descriptor set in a class definition. The only things I can find that accomplish something like this requires that the getter/setter be hooked up during the above obj creation, and cannot be easily reused on multiple attributes or objects.

You can try 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

I don't know what your environment is (it's only tagged javascript), but ES6 Proxies provide this flexibility of get/set

copied 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

You can either use Object.defineProperty to define getter and setter, or simply do it in an object initialiser :

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

I believe you are trying to do something like this: (Another way of doing what Oriol has done in his answer.)

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

Everything is separated, such that the function can be reused meanwhile values are kept separated from all other object's value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM