侦听 JavaScript 中的变量更改

2022-08-29 22:43:30

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


答案 1

这个问题最初发布于2009年,大多数现有答案要么过时,要么无效,要么需要包含大型臃肿的库:

从 2018 年起,您现在可以使用 Proxy 对象来监视(和拦截)对对象所做的更改。它是专门为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

  1. 该对象在较旧的浏览器(如 IE11)中不可用,并且 polyfill 无法完全复制功能。ProxyProxy
  2. 代理对象在特殊对象(例如 )时并不总是像预期的那样运行 -- 该对象最好与普通对象或数组配对。DateProxy

如果您需要观察对嵌套对象所做的更改,则需要使用专门的库,例如Observible 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}}]

 

答案 2

是的,现在这完全有可能!

我知道这是一个旧的线程,但现在使用访问器(getters和setters)可以达到这种效果:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Defining_getters_and_setters

您可以像这样定义一个对象,其中表示字段:aInternala

x = {
  aInternal: 10,
  aListener: function(val) {},
  set a(val) {
    this.aInternal = val;
    this.aListener(val);
  },
  get a() {
    return this.aInternal;
  },
  registerListener: function(listener) {
    this.aListener = listener;
  }
}

然后,您可以使用以下命令注册侦听器:

x.registerListener(function(val) {
  alert("Someone changed the value of x.a to " + val);
});

因此,每当任何更改 的值时,都会触发侦听器函数。运行以下行将出现警报弹出窗口:x.a

x.a = 42;

在此处查看示例:https://jsfiddle.net/5o1wf1bn/1/

您还可以使用侦听器数组而不是单个侦听器槽,但我想为您提供最简单的示例。