监听JavaScript中的变量更改

本秂侑毒 提交于 2020-02-27 15:28:23

某个变量的值更改时,是否可能在JS中触发事件? 接受JQuery。


#1楼

对于几年后的调优:

提供了适用于大多数浏览器(和IE6 +)的解决方案,该解决方案使用onpropertychange事件和更新的规范defineProperty。 轻微的缺点是您需要使变量成为dom对象。

详细信息:

http://johndyer.name/native-browser-get-set-properties-in-javascript/


#2楼

抱歉,打了个旧话题,但是对于那些不了解Eli Grey的示例如何工作的人,这里有一些手册:

var test = new Object();
test.watch("elem", function(prop,oldval,newval){
    //Your code
    return newval;
});

希望这可以帮助某人


#3楼

不直接:您需要一对具有某种“ addListener / removeListener”接口的吸气剂/吸气剂或NPAPI插件(但这完全是另一回事了)。


#4楼

没有。

但是,如果真的那么重要,则有两种选择(第一种经过测试,第二种未经测试):

首先,使用setter和getter,如下所示:

var myobj = {a : 1};

function create_gets_sets(obj) { // make this a framework/global function
    var proxy = {}
    for ( var i in obj ) {
        if (obj.hasOwnProperty(i)) {
            var k = i;
            proxy["set_"+i] = function (val) { this[k] = val; };
            proxy["get_"+i] = function ()    { return this[k]; };
        }
    }
    for (var i in proxy) {
        if (proxy.hasOwnProperty(i)) {
            obj[i] = proxy[i];
        }
    }
}

create_gets_sets(myobj);

那么您可以执行以下操作:

function listen_to(obj, prop, handler) {
    var current_setter = obj["set_" + prop];
    var old_val = obj["get_" + prop]();
    obj["set_" + prop] = function(val) { current_setter.apply(obj, [old_val, val]); handler(val));
}

然后将侦听器设置为:

listen_to(myobj, "a", function(oldval, newval) {
    alert("old : " + oldval + " new : " + newval);
}

其次,我实际上忘记了,我会在考虑的同时提交:)

编辑:哦,我记得:)您可以将手表放在值上:

给定上面的myobj,上面带有“ a”:

function watch(obj, prop, handler) { // make this a framework/global function
    var currval = obj[prop];
    function callback() {
        if (obj[prop] != currval) {
            var temp = currval;
            currval = obj[prop];
            handler(temp, currval);
        }
    }
    return callback;
}

var myhandler = function (oldval, newval) {
    //do something
};

var intervalH = setInterval(watch(myobj, "a", myhandler), 100);

myobj.set_a(2);

#5楼

作为Luke Schafer的答案请注意 :这是他的原始帖子;但是,此处的要点在编辑后仍然有效 ),我还建议使用一对Get / Set方法来访问您的值。

但是,我建议您进行一些修改(这就是为什么我要发布...)。

该代码的问题在于,可以直接访问对象myobj的字段a ,因此可以在不触发侦听器的情况下对其进行访问/更改其值:

var myobj = { a : 5, get_a : function() { return this.a;}, set_a : function(val) { this.a = val; }}
/* add listeners ... */
myobj.a = 10; // no listeners called!

封装形式

因此,为了确保确实调用了侦听器,我们必须禁止对该字段a直接访问。 怎么做? 使用闭包

var myobj = (function() { // Anonymous function to create scope.

    var a = 5;            // 'a' is local to this function
                          // and cannot be directly accessed from outside
                          // this anonymous function's scope

    return {
        get_a : function() { return a; },   // These functions are closures:
        set_a : function(val) { a = val; }  // they keep reference to
                                            // something ('a') that was on scope
                                            // where they were defined
    };
})();

现在,您可以用同样的方法来创建并添加监听卢克提出,但你可以放心,有来读取或写入没有可能的方式a要被忽视!

以编程方式添加封装的字段

仍然在Luke的轨道上,我现在提出一种简单的方法,即通过简单的函数调用将封装的字段以及相应的getter / setter添加到对象。

请注意,这仅适用于值类型 。 为了使它与引用类型一起使用 ,必须实现某种深度复制 (例如,参见副本)。

function addProperty(obj, name, initial) {
    var field = initial;
    obj["get_" + name] = function() { return field; }
    obj["set_" + name] = function(val) { field = val; }
}

它的工作原理与以前相同:我们在函数上创建一个局部变量,然后创建一个闭包。

如何使用它? 简单:

var myobj = {};
addProperty(myobj, "total", 0);
window.alert(myobj.get_total() == 0);
myobj.set_total(10);
window.alert(myobj.get_total() == 10);
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!