在getter 和setter 的帮助下,你可以定义一个JavaScript 类来做这样的事情。
首先,我们定义名为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;
}
}
假设我们想监听money的变化,让我们用初始资金0创建一个MonitoredVariable的实例:
const money = new MonitoredVariable(0);
然后我们可以使用money.val获取或设置它的值:
console.log(money.val); // Get its value
money.val = 2; // Set its value
由于我们没有为它定义任何监听器,money.val 更改为 2 后没有什么特别的事情发生。
现在让我们定义一些监听器。我们有四个可用的听众:beforeSet、beforeChange、afterChange、afterSet。
当您使用money.val = newValue 更改变量的值时,将依次发生以下情况:
- money.beforeSet(newValue, oldValue);
- money.beforeChange(newValue, oldValue); (如果它的值没有改变,将被跳过)
- money.val = newValue;
- money.afterChange(newValue, oldValue); (如果它的值没有改变,将被跳过)
- money.afterSet(newValue, oldValue);
现在我们定义afterChange监听器,它只在money.val发生变化后触发(而afterSet即使新值与旧值相同也会被触发):
money.afterChange = (newValue, oldValue) => {
console.log(`Money has been changed from ${oldValue} to ${newValue}`);
};
现在设置一个新值3,看看会发生什么:
money.val = 3;
您将在控制台中看到以下内容:
Money has been changed from 2 to 3
完整代码见https://gist.github.com/yusanshi/65745acd23c8587236c50e54f25731ab。