Listening for variable changes in JavaScript

后端 未结 22 2787
自闭症患者
自闭症患者 2020-11-21 06:57

Is it possible to have an event in JS that fires when the value of a certain variable changes? JQuery is accepted.

22条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-11-21 07:12

    With the help of getter and setter, you can define a JavaScript class that does such a thing.

    First, we define our class called MonitoredVariable:

    class MonitoredVariable {
      constructor(initialValue) {
        this._innerValue = initialValue;
        this.beforeSet = (newValue, oldValue) => {};
        this.beforeChange = (newValue, oldValue) => {};
        this.afterChange = (newValue, oldValue) => {};
        this.afterSet = (newValue, oldValue) => {};
      }
    
      set val(newValue) {
        const oldValue = this._innerValue;
        // newValue, oldValue may be the same
        this.beforeSet(newValue, oldValue);
        if (oldValue !== newValue) {
          this.beforeChange(newValue, oldValue);
          this._innerValue = newValue;
          this.afterChange(newValue, oldValue);
        }
        // newValue, oldValue may be the same
        this.afterSet(newValue, oldValue);
      }
    
      get val() {
        return this._innerValue;
      }
    }
    

    Assume that we want to listen for money changes, let's create an instance of MonitoredVariable with initial money 0:

    const money = new MonitoredVariable(0);
    

    Then we could get or set its value using money.val:

    console.log(money.val); // Get its value
    money.val = 2; // Set its value
    

    Since we have not defined any listeners for it, nothing special happens after money.val changes to 2.

    Now let's define some listeners. We have four listeners available: beforeSet, beforeChange, afterChange, afterSet. The following will happen sequentially when you use money.val = newValue to change variable's value:

    1. money.beforeSet(newValue, oldValue);
    2. money.beforeChange(newValue, oldValue); (Will be skipped if its value not changed)
    3. money.val = newValue;
    4. money.afterChange(newValue, oldValue); (Will be skipped if its value not changed)
    5. money.afterSet(newValue, oldValue);

    Now we define afterChange listener which be triggered only after money.val has changed (while afterSet will be triggered even if the new value is the same as the old one):

    money.afterChange = (newValue, oldValue) => {
      console.log(`Money has been changed from ${oldValue} to ${newValue}`);
    };
    

    Now set a new value 3 and see what happens:

    money.val = 3;
    

    You will see the following in the console:

    Money has been changed from 2 to 3
    

    For full code, see https://gist.github.com/yusanshi/65745acd23c8587236c50e54f25731ab.

提交回复
热议问题