变量属性更改时的触发事件

时间:2019-06-10 12:10:53

标签: javascript

我正在创建一个包含多个属性的可重用对象。我想在对象内触发一个事件,当通过赋值更改特定属性时,该事件将更新其自身的一些属性。我读过类似的文章,但他们使用的只是一个对象。我该如何实现?

如果这是基本知识,但我真的没有接受过正式培训,我深表歉意是JavaScript或精通JavaScript的工作原理。

我还要补充一点,这是在IE11及更高版本中应该可以使用的功能。

我已经从中测试了该方法,但不幸的是,我不太了解如何在我的案子中实现该方法。

Listening for variable changes in JavaScript

var test;

function myObject(){
  this.dataSource = null; 
  this.changeEvent = function(val){
    //do something inside
  }
}

test = new myObject();
test.dataSource = 'dataSource'; //trigger changeEvent() inside myObject

4 个答案:

答案 0 :(得分:0)

您可以将dataSource的值存储在本地存储中,然后进行比较并检查其是否已更改。

var test;
function myObject()
{
  this.dataSource = null; 
  this.changeEvent = function(val)
  {
    console.log("Value has been changed.");
  }
}
test = new myObject();
test.dataSource = 'dataSource';
console.log("Before change" + test.dataSource);
localStorage.setItem("dataSource", test.dataSource);
var newVal = "dtSrc";
test.dataSource = newVal;
var originalVal = localStorage.getItem("dataSource");
console.log("After change" + test.dataSource);
if(newVal == originalVal)
    console.log("Value has not changed.");
else
    test.changeEvent();

让我知道它是否对您有用。如果没有,请告知我预期的输出。

答案 1 :(得分:0)

好的,所以我将从您建议的方法开始,看来您喜欢这种方法。

对不起,如果这似乎很明显,但可以更好地解释!

基本上watch监视对象(例如数据源)中的属性,并在分配了新值后触发callback函数。因此,观看需要两个参数-观看内容和操作(当您正在观看的属性发生更改时)。

此方法的警告是它是非标准的,并且未由其他浏览器实现。虽然,我们可以获得一个polyfill(如果它不存在,则将其声明)。

https://gist.github.com/eligrey/384583

Mozilla自己的文档中的警告:

  

弃用警告:请勿使用watch()和unwatch()!这两个   方法仅在版本58之前的Firefox中实现,它们是   在Firefox 58+中已弃用并删除。此外,使用观察点   对性能有严重的负面影响,尤其是   在全局对象(例如窗口)上使用时。您通常可以使用   setter和getter或代理。

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

因此,要使用手表的polyfil来实现(感谢Eli Gray的Polyfill)

首先,注册polyfill(将其放置在将在JS中进行其他操作之前运行的位置,或将其放入polyfill.js文件中,然后将其首先导入HTML页面中!)

/*
 * object.watch polyfill
 *
 * 2012-04-03
 *
 * By Eli Grey, http://eligrey.com
 * Public Domain.
 * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
 */

// object.watch
if (!Object.prototype.watch) {
    Object.defineProperty(Object.prototype, "watch", {
          enumerable: false
        , configurable: true
        , writable: false
        , value: function (prop, handler) {
            var
              oldval = this[prop]
            , newval = oldval
            , getter = function () {
                return newval;
            }
            , setter = function (val) {
                oldval = newval;
                return newval = handler.call(this, prop, oldval, val);
            }
            ;

            if (delete this[prop]) { // can't watch constants
                Object.defineProperty(this, prop, {
                      get: getter
                    , set: setter
                    , enumerable: true
                    , configurable: true
                });
            }
        }
    });
}

// object.unwatch
if (!Object.prototype.unwatch) {
    Object.defineProperty(Object.prototype, "unwatch", {
          enumerable: false
        , configurable: true
        , writable: false
        , value: function (prop) {
            var val = this[prop];
            delete this[prop]; // remove accessors
            this[prop] = val;
        }
    });
}

然后使用(使用您的示例);

var test;

**function myObject(){
  this.dataSource = null; 
  this.changeEvent = function (id, oldval, newval) {
    console.log(id + ' changed from ' + oldval + ' to ' + newval);
    return newval;
 }
  this.watch('datasource', this.changeEvent);
}**

test = new myObject();
test.dataSource = 'dataSource'; //trigger changeEvent() inside myObject

但是,我会研究事件侦听器并在对象发生更改时触发事件-但是该解决方案应该对您有用,尤其是对于watch

Listening for variable changes in JavaScript

答案 2 :(得分:0)

您可以使用:

var myObject = {
    _dataSource: null,
    changeEvent : function(val){
        //do something inside
        alert(val);
    }
};
Object.defineProperty(myObject, "dataSource", {
    get: function(){
        return this._dataSource;
    }, 
    set: function(newValue){
        this._dataSource=newValue;
        this.changeEvent(this.dataSource);
    }
});

myObject.dataSource= "dataSource";

答案 3 :(得分:0)

创建对象时,请将其包装在Proxy中。

  

Proxy对象用于定义基本操作的自定义行为(例如,属性查找,赋值,枚举,函数调用等)。

实施set陷阱,以执行所需的内部更改。