是否有可能在JS中有一个事件,当某个变量的值发生变化时触发?JQuery被接受。
当前回答
使用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>
其他回答
这个问题最初发布于2009年,现有的大多数答案要么过时,无效,要么需要包含庞大的库:
对象。观看和反对。Observe都已弃用,不应该使用。 onPropertyChange是一个DOM元素事件处理程序,只在某些版本的IE中工作。 object . defineproperty允许您将对象属性设置为不可变的,这将允许您检测尝试的更改,但它也将阻止任何更改。 定义setter和getter是可行的,但是它需要大量的设置代码,并且当您需要删除或创建新属性时,它不能很好地工作。
截至2018年,您现在可以使用代理对象来监视(和拦截)对对象的更改。它是专门为OP试图做的事情而建造的。这里有一个基本的例子:
var targetObj = {};
var targetProxy = new Proxy(targetObj, {
set: function (target, key, value) {
console.log(`${key} set to ${value}`);
target[key] = value;
return true;
}
});
targetProxy.hello_world = "test"; // console: 'hello_world set to test'
Proxy对象唯一的缺点是:
Proxy对象在旧的浏览器(如IE11)中不可用,而且polyfill不能完全复制Proxy功能。 代理对象对于特殊对象(例如Date)并不总是表现得像预期的那样——代理对象最好与普通对象或数组配对。
如果你需要观察对嵌套对象所做的更改,那么你需要使用一个专门的库,如Observable Slim(我已经发布了)。它是这样工作的:
var test = {testing:{}};
var p = ObservableSlim.create(test, true, function(changes) {
console.log(JSON.stringify(changes));
});
p.testing.blah = 42; // console: [{"type":"add","target":{"blah":42},"property":"blah","newValue":42,"currentPath":"testing.blah",jsonPointer:"/testing/blah","proxy":{"blah":42}}]
不是直接的:你需要一个“addListener/removeListener”接口的一对getter/setter…或者一个NPAPI插件(但这完全是另一个故事)。
这个问题是关于变量的,而不是对象属性!因此,我的方法是利用窗口对象及其自定义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
Utils = {
eventRegister_globalVariable : function(variableName,handlers){
eventRegister_JsonVariable(this,variableName,handlers);
},
eventRegister_jsonVariable : function(jsonObj,variableName,handlers){
if(jsonObj.eventRegisteredVariable === undefined) {
jsonObj.eventRegisteredVariable={};//this Object is used for trigger event in javascript variable value changes ku
}
Object.defineProperty(jsonObj, variableName , {
get: function() {
return jsonObj.eventRegisteredVariable[variableName] },
set: function(value) {
jsonObj.eventRegisteredVariable[variableName] = value; handlers(jsonObj.eventRegisteredVariable[variableName]);}
});
}
对于那些几年后收听的人来说:
大多数浏览器(和IE6+)都有一个解决方案,它使用onpropertychange事件和更新的规范defineProperty。有一点需要注意的是,您需要将变量设置为dom对象。
详情:
http://johndyer.name/native-browser-get-set-properties-in-javascript/
推荐文章
- 如何在Typescript中解析JSON字符串
- jQuery的“输入”事件
- Javascript reduce()在对象
- 在angularJS中& vs @和=的区别是什么
- 错误"Uncaught SyntaxError:意外的标记与JSON.parse"
- JavaScript中的querySelector和querySelectorAll vs getElementsByClassName和getElementById
- 给一个数字加上st, nd, rd和th(序数)后缀
- 如何以编程方式触发引导模式?
- setTimeout带引号和不带括号的区别
- 在JS的Chrome CPU配置文件中,'self'和'total'之间的差异
- 用javascript检查输入字符串中是否包含数字
- 如何使用JavaScript分割逗号分隔字符串?
- 在Javascript中~~(“双波浪号”)做什么?
- 谷歌chrome扩展::console.log()从后台页面?
- 未捕获的SyntaxError: