1

Given the following:

x = {
  aInternal: 10,
  aListener: function(val) {},
  set a(val) {
    this.aInternal = val;
    this.aListener(val);
  },
  get a() {
    return this.aInternal;
  },
  registerListener: function(listener) {
    this.aListener = listener;
  }
}

x.registerListener(function(val) {
  console.log("Someone changed the value of x.a to " + val);
});

x.a = 42; //Writes to the console that the variable has changed

How can I use an array of listeners so that I have, x.a, x.b and so-on?

Dshiz
  • 3,099
  • 3
  • 26
  • 53
  • What are you trying to achieve? Maybe you can find what you need in the RxJs library. – Adrian Brand Jul 02 '20 at 04:14
  • Thanks @AdrianBrand I'm trying to accomplish this in pure javascript without any libraries. – Dshiz Jul 02 '20 at 04:15
  • What is it you are trying to achieve? A generic listener that fires when any property on the object changes? – Adrian Brand Jul 02 '20 at 04:16
  • The code watches for a change to any defined variable and writes to the console when it happens. I would like to make `x.b` work exactly like `x.a` but allow for an array of variables. – Dshiz Jul 02 '20 at 04:20
  • @Teemu sorry - please try the code again. There is a jsfiddle here, also: https://jsfiddle.net/5o1wf1bn/1/ – Dshiz Jul 02 '20 at 04:24
  • OK, now this makes some sense. Only that I'm not sure what you mean with "array of variables" ... Maybe you need [Proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) ..? – Teemu Jul 02 '20 at 04:27
  • @Teemu an array of *listeners* not variables.. – Dshiz Jul 02 '20 at 04:29
  • https://stackoverflow.com/questions/3112793/how-can-i-define-a-default-getter-and-setter-using-ecmascript-5 look like exactly what you want – Adrian Brand Jul 02 '20 at 04:30
  • @AdrianBrand Interesting.. I was going that direction--in a way--when I started researching "custom elements" – Dshiz Jul 02 '20 at 04:34

1 Answers1

0

A proxy is what you want

var proxyHandler = {
    get: function(obj, name){
        console.log("you're getting property " + name);
        return obj[name];
    },
    set: function(obj, name, value) {
        console.log("you're setting property " + name);
        obj[name] = value;
    }
}

var underlyingObj = {};

// use x instead of underlyingObj to use get/set interceptor functions
var x = new Proxy(underlyingObj, proxyHandler);

x.a = 5;

console.log(x.a);

x.b = 10;

console.log(x.b);
Adrian Brand
  • 20,384
  • 4
  • 39
  • 60
  • Thanks - let me work through this a bit to understand it.. – Dshiz Jul 02 '20 at 04:53
  • Could you expand a bit more on what you mean by "use x instead of underlyingObj to use get/set interceptor functions"? – Dshiz Jul 02 '20 at 04:59
  • x is the proxy object, when you call x.a it calls the get function from the proxy handler passing in underlyingObj and 'a' as the paramaters. – Adrian Brand Jul 02 '20 at 05:01