JavaScript中怎么监控变量变化? 总结了下4种方法.
看到一篇不错的国外整理文章,特此记录下. 使用原生js监控变量的变化主要有6种,具体如下.
1.使用setInterval轮询检测
<script> /** * 轮询检测变量变化 * @param varName '要检测的变量名称' * @param callback '变量变化后执行的函数' * @param checkTimes '需要检测几次.0表示一直检测,1为检测1次就停止检测,以此类推' */ function watch(varName, callback, checkTimes = 1) { clearcheck = setInterval(repeatcheck, 500, varName);//500毫秒检测一次 let current = 0; let oldvalue = window[varName] function repeatcheck(varName) { if (window[varName] !== oldvalue) { current++; callback && callback(oldvalue, window[varName], current) if (checkTimes > 0 && current > checkTimes) { clearInterval(clearcheck); } console.log(`${varName} value changed from ${oldvalue} to ${window[varName]} (${current} times)`); oldvalue = window[varName] } } } //用法 var myVar = 'hello';//初始化要检测的变量,一定要声明为全局变量 let title = 'beautiful!'; watch('myVar', function (oldValue, newValue, changeTImes) {//changeTImes: 改变的次数 //do something you want.做你的逻辑 alert(`changeTime ${changeTImes}: ; now value is: ${newValue}`) }, 0) myVar = 'world';//改变值,测试下 </script>
2.监听DOM变化
//设置隐藏的dom <div id="watchdiv" style='visibility:hidden;width:0;height:0'>0</div> <script> document.getElementById('watchdiv') .addEventListener('DOMSubtreeModified', function () { //做你的逻辑 console.log("value changed to " + document.getElementById('watchdiv').innerHTML) }); </script>
3.为对象的每个属性设置setter和getter
缺点就是需要较多的设置代码; 同时对于新增或删除的属性是通知不到的.为属性设置setter和getter官方文档
看下这个简单栗子,很容易就会用了.const o = { a: 7, get b() { return this.a + 1; }, set c(x) { this.a = x / 2; } }; console.log(o.a); // 7 console.log(o.b); // 8 <-- 这时get b()会被调用 o.c = 50; // <-- 这时set c(x)会被调用 console.log(o.a); // 25
4.使用代理对象proxy object (都2202年了推荐使用这个)
proxy object方法简单说就是他能为一个目标对象创建一个代理对象,所有操作都会被代理对象拦截下来且可被重新定义操作.(我们操作代理对象而不是直接操作目标对象).举个简单栗子很快就会明白.
let targetObj = {}; let targetProxy = new Proxy(targetObj, { set: function (target, key, value) {//设置对象属性会被调用 //做你的逻辑 console.log(`${key} set to ${value}`); target[key] = value; return true; }, get: function (target, key) {//访问对象属性会调用 //做你的逻辑 console.log(`access the ${key}`) } }); targetProxy.a = 'test'//注意是操作代理对象,而不是直接操作目标对象
综上,第3和4方法会比较好用,其中推荐可采用第4种方法.
参考:
https://stackoverflow.com/questions/1759987/listening-for-variable-changes-in-javascript
https://lage.us/Javascript-Watch-Variables-for-Change.html