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


当前回答

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

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

你可以像这样定义一个对象,其中inner表示字段a:

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/

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

其他回答

这是一个老线程,但我在使用Angular寻找解决方案时偶然发现了第二高的答案(自定义侦听器)。虽然这个解决方案是可行的,但angular有一个更好的内置方法来解决这个问题,使用@Output和事件发射器。在自定义监听器回答中的例子:

ChildComponent.html

<button (click)="increment(1)">Increment</button>

ChildComponent.ts

import {EventEmitter, Output } from '@angular/core';

@Output() myEmitter: EventEmitter<number> = new EventEmitter<number>();

private myValue: number = 0;

public increment(n: number){
  this.myValue += n;

  // Send a change event to the emitter
  this.myEmitter.emit(this.myValue);
}

ParentComponent.html

<child-component (myEmitter)="monitorChanges($event)"></child-component>
<br/>
<label>{{n}}</label>

ParentComponent.ts

public n: number = 0;

public monitorChanges(n: number){
  this.n = n;
  console.log(n);
}

现在每次单击子按钮时都会更新非父按钮。工作stackblitz

//ex:
/*
var x1 = {currentStatus:undefined};
your need is x1.currentStatus value is change trigger event ?
below the code is use try it.
*/
function statusChange(){
    console.log("x1.currentStatus_value_is_changed"+x1.eventCurrentStatus);
};

var x1 = {
    eventCurrentStatus:undefined,
    get currentStatus(){
        return this.eventCurrentStatus;
    },
    set currentStatus(val){
        this.eventCurrentStatus=val;
      //your function();
    }
};

or

/*  var x1 = {
eventCurrentStatus:undefined,
currentStatus : {
    get : function(){
        return Events.eventCurrentStatus
        },
    set : function(status){
        Events.eventCurrentStatus=status;

    },
}*/
console.log("eventCurrentStatus = "+ x1.eventCurrentStatus);
x1.currentStatus="create"
console.log("eventCurrentStatus = "+ x1.eventCurrentStatus);
x1.currentStatus="edit"
console.log("eventCurrentStatus = "+ x1.eventCurrentStatus);
console.log("currentStatus = "+ x1.currentStatus);

or

/* global variable ku*/
    var jsVarEvents={};
    Object.defineProperty(window, "globalvar1", {//no i18n
        get: function() { return window.jsVarEvents.globalvarTemp},
        set: function(value) { window.window.jsVarEvents.globalvarTemp = value; }
    });
    console.log(globalvar1);
    globalvar1=1;
    console.log(globalvar1);

这就是我所做的:调用JSON。Stringify两次并比较两个字符串…

缺点:

你只能知道整个物体是否发生了变化 您必须手动检测更改 你最好在对象中只有基本字段(没有属性,没有函数……)

@akira和@mo-d-genesis的解决方案可以进一步简化,因为在这个例子中DOM操作不依赖于状态:

CodePen

const render = (val) => {
  document.getElementById("numberDiv").innerHTML = val;
};

state = {
  _value_internal: undefined,
  set value(val) {
    // 1. set state value
    this._value_internal = val;
    // 2. render user interface
    render(val);
  },
  get value() {
    return this._value_internal;
  },
};

const onClick = () => {
  state.value = state.value + 1; // state change leads to re-render!
};

// set default value
state.value = 0;

对应的html:

<div id="numberDiv"></div>

<button onclick="onClick()">
  Click to rerender
</button>

备注:

我重命名了变量和函数,以更好地反映它们的语义。 仅供参考:通过改变变量,Svelte提供了非常类似的反应行为

请记住,最初的问题是针对变量的,而不是针对对象的;)

除了上面所有的答案,我创建了一个名为thewatch .js的小库, 在javascript中使用相同的方法来捕捉和回调普通全局变量的变化。

与JQUERY变量兼容,不需要使用object,如果需要,可以直接传递几个变量的ARRAY。

如果有帮助的话……: https://bitbucket.org/esabora/forthewatch基本上你只需要调用这个函数: watchIt(“theVariableToWatch”、“varChangedFunctionCallback”);

如果不相关,先说句抱歉。