JavaScript:如何持续监测变量值

11

如何不断检查变量的值。例如:

if(variable == 'value'){
    dosomething();
}

如果我不断地循环它,这将起作用,但是是否有一种有效的方法在变量设置为该值时立即触发它?


1
用一个计时器。我认为没有其他办法。 - Pekka
有一些实现特定的方法。你有目标浏览器吗,还是尽可能多的浏览器都要兼容? - Hemlock
我正在开发一个移动应用程序,因此我支持所有最新的Javascript技术和最佳实践,这些JS会被转换为Objective C。我不设置函数的值,而是在用户点击按钮时,从第三方动态获取该函数的值。我正在等待该值从默认值更改为其他任何值。 - Connor
1
那么,我可以假设你将在webkit上运行这个程序吗?如果是这样,也许你应该声明一下,并添加一个webkit和/或safari标签,因为它可能有其他浏览器无法实现的方法。 - slebetman
6个回答

12
此解决方案使用已弃用的API。计算属性和代理是更好的选择,除了在最古老的浏览器上。有关如何使用这些内容的示例,请参见K2Span的答案

Object.watch

监视属性被赋值并在发生时运行函数。

Object.watch() for all browsers?介绍了在不支持本地化该特性的浏览器上执行Object.watch的跨浏览器方法。


1
最有效的方法是,如果您想要监视全局变量,可以使用window.watch('variable', handler)。 - Amjad Masad
全局数组怎么样? - maazza
@maazza,你想知道全局数组的内容何时更改,还是当对全局属性进行赋值时更改引用的数组? - Mike Samuel
1
通常情况下,应尽可能避免使用watch()和unwatch()方法。这两种方法仅在Gecko中实现,并且主要用于调试。 - Mark Carpenter Jr
1
这个方法从 Firefox 58 版本开始已经被弃用,并且完全不推荐使用。 - ali
显示剩余6条评论

8
Object.defineProperty(Object.prototype, 'watch', {
    value: function(prop, handler){
        var setter = function(val){
            return val = handler.call(this, val);
        };
        Object.defineProperty(this, prop, {
            set: setter
        });
    }
});

如何使用:

var obj = {};

obj.watch('prop', function(value){
    console.log('wow!',value);
});

obj.prop = 3;

3
你能否解释一下这是怎么工作的?它似乎非常有效,但我并没有真正明白它的原理 :) - 1252748
我认为这个答案很棒。它将回调函数注入到对象属性(被监视的变量)的“set”属性中。 - Gonki
这里假设被监听的属性并未被已有函数覆盖。这将会覆盖所有已存在的设置器代码。那么如何实现 obj.unwatch() ?如果其它代码已经在监听此属性,这会覆盖先前的监听吗?看起来更好的解决方案可能是类似于 obj.addListener('change', prop, listener); 这样的形式。 - user1944491

6

使用 setInterval:

var key = ''
setInterval(function(){
  if(key == 'value'){
    dosomething();
  }
}, 1000);

这是一个针对不同问题的有用答案。大多数情况下,您不会发现属性更改,因为它们会在函数的间隙中发生。 - James Moore

4

正如@Pekka所评论的,您可以定时轮询变量。如果所有更改变量的代码都是您自己的,则更好的解决方案是不仅直接设置变量,而是让所有设置器调用一个函数。该函数可以设置变量并执行您需要的任何其他处理。

function setValue(value) {
    myVariable = value;
    notifyWatchers();
}

4

如果您封装变量,使得该值只能通过调用函数进行设置,那么这将给您检查该值的机会。

function ValueWatcher(value) {
    this.onBeforeSet = function(){}
    this.onAfterSet = function(){}

    this.setValue = function(newVal) {
        this.onBeforeSet(value, newVal)
        value = newVal;
        this.onAfterSet(newVal)
    }
    this.getValue = function() {
        return value;
    }
}

var name = new ValueWatcher("chris");

wacthedName.onBeforeChange = function(currentVal, newVal) {
    alert("about to change from" + currentVal + " to " + newVal);
}

name.setValue("Connor");

0

我曾经遇到过类似的问题,但是通过使用之前已经用过的定时函数,我成功地解决了它。即使您没有定时函数,也很容易创建;

var rand = 0
setInterval(function senseConst () {if (rand = 0) {rand = x}, 10);
//x could be equal to the variables value that you want to check

我使用以下代码来不断获取页面长度的变量:

var widthSensorOutput = 0
setInterval(function senseConst () {if (widthSensorOutput = 0) {widthSensorOutput = document.getElementById('widthSensor').clientWidth}, 10);
//'widthSensor' is a div with the width equal to 100%

我不确定这是否是解决您问题的最佳方法,但对我有效。明确一下,这是Chandu提供的相同基本代码,只是我添加了您在进入函数后应该执行的操作,这已经非常明显了。我没有理解Chandu的帖子,也没有意识到他们使用了相同的根代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接