是否有可能在JS中有一个事件,当某个变量的值发生变化时触发?JQuery被接受。


当前回答

如果你正在使用jQuery {UI}(每个人都应该使用:-)),你可以使用.change()和一个隐藏的<input/>元素。

其他回答

使用Prototype: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

/ /控制台 函数print(t) { var c = document.getElementById('console'); c.innerHTML = c.innerHTML + '<br />' + t; } / /演示 var myVar = 123; Object.defineProperty(this, 'varWatch', { get: function(){返回myVar;}, 集合:函数(v) { myVar = v; 打印(“价值变化!新值:' + v); } }); 打印(varWatch); varWatch = 456; 打印(varWatch); < pre id =“控制台”> < / >之前

其他的例子

// Console function print(t) { var c = document.getElementById('console'); c.innerHTML = c.innerHTML + '<br />' + t; } // Demo var varw = (function (context) { /** * Declare a new variable. * * @param {string} Variable name. * @param {any | undefined} varValue Default/Initial value. * You can use an object reference for example. */ return function (varName, varValue) { var value = varValue; Object.defineProperty(context, varName, { get: function () { return value; }, set: function (v) { value = v; print('Value changed! New value: ' + value); } }); }; })(window); varw('varWatch'); // Declare without initial value print(varWatch); varWatch = 456; print(varWatch); print('---'); varw('otherVarWatch', 123); // Declare with initial value print(otherVarWatch); otherVarWatch = 789; print(otherVarWatch); <pre id="console"> </pre>

这个问题是关于变量的,而不是对象属性!因此,我的方法是利用窗口对象及其自定义getter /setter,然后像“正常”变量(不像对象属性)一样使用/更改变量。

最简单的方法是@José Antonio Postigo在他的回答中(我投票了那个答案)。我在这里想做的是将其简化为一个更简单的“creator”函数(这样即使不理解对象getter /setter的人也可以轻松使用它)。

一个活生生的例子在这里:https://codepen.io/dimvai/pen/LYzzbpz

这是你必须拥有的一般“creator”函数:

let createWatchedVariable = (variableName,initialValue,callbackFunction) => {
    // set default callback=console.log if missing
    callbackFunction ??= function(){console.log(variableName+" changed to " + window[variableName])};
    // the actual useful code:
    Object.defineProperty(window, variableName, {
      set: function(value) {window["_"+variableName] = value; callbackFunction()},
      get: function() {return window["_"+variableName]}
    });
    window[variableName]=initialValue??null;
};

然后,不要使用var或let来声明变量,而是使用下面的语句:

// 1st approach - default callback//    
createWatchedVariable ('myFirstVariable',12);  
// instead of: let myFirstVariable = 12;

或者,为了使用你的自定义回调(而不是默认的console.log)使用:

// 2nd approach - set a custom callback//
var myCallback = ()=>{/*your custom code...*/}
// now use callback function as the third optional argument
createWatchedVariable('mySecondVariable',0,myCallback);

就是这样!现在,你可以像改变一个“正常”变量一样改变它:

myFirstVariable = 15;      // logs to console
myFirstVariable++;         // logs to console
mySecondVariable = 1001;   // executes your custom code
mySecondVariable++;        // executes your custom code

No.

但是,如果这真的很重要,你有两个选择(第一个是测试,第二个不是):

首先,使用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);

你正在寻找的功能可以通过使用“defineProperty()”方法来实现——这只适用于现代浏览器:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

我写了一个jQuery扩展,有一些类似的功能,如果你需要更多的跨浏览器支持:

https://github.com/jarederaj/jQueue

对象的队列回调的jQuery小扩展 变量、对象或键的存在。你可以分配任意数量的 对可能受影响的任意个数的数据点的回调 进程在后台运行。jQueue监听并等待 您指定的这些数据开始存在,然后发射 纠正回调函数的参数。

对于那些几年后收听的人来说:

大多数浏览器(和IE6+)都有一个解决方案,它使用onpropertychange事件和更新的规范defineProperty。有一点需要注意的是,您需要将变量设置为dom对象。

详情:

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