5

这可能看起来很傻,但是在这个时代,如果数组的内容发生了变化,人们应该能够期望 JS 引发一个事件。

关于在变量更改时获得通知的几个问题(定义 getter 或 setter)。似乎有办法做到这一点(至少对于大多数浏览器,包括 IE6+)

我的问题是,如果数组中的项目发生更改,我会尝试收到通知:

    var ar = ["one", "two", "three"];
    // setting the whole array will call the custom setter method
    // (assuming you defined it)

    ar = ["one", "three", "five"];

    // however, this will only call the getter method and won't call the setter
    // without defining custom setters for every item in the array.  

    ar[1] = "two";

显然,我试图避免强迫编码人员使用老式的 Java 风格.getVale().setValue()函数来访问/修改数据。

4

3 回答 3

3

简而言之:不,你不能。您会注意到数组不提供任何事件分派机制,并且它们的 API 不包含任何回调类型的功能。

更长的时间:正如其他人所指出的,可以包装数组......而且还可以轮询数组内容:

function watchArray(arr, callback) {
    var oldVal = "" + arr;
    setInterval(function() {
        var curVal = "" + arr;
        if (curVal != oldVal) {
            callback();
            oldVal = curVal;
        }
    }, 100);
}

但是这种方法有一些明显的问题:它会轮询,观察一堆数组会变慢等等。

于 2012-06-06T16:22:34.327 回答
0

好的,根据@David Wolever 的代码和其他评论,实际上有一个解决方案:

使用John Dyer的注释来实现 addProperty 方法。在 getter 方法中放置一个 setTimeout 以在读取发生后不久与原始值进行比较:

addProperty(myObject, 'vals',
    function () {
        var _oldVal = "" + this._val;
        var _parent = this;
        console.log('getter!');
        setTimeout(function () {
            var curVal = "" + _parent._val;
            if (curVal != _oldVal)
                console.log('array changed!');
        }, 200);
        return this._val;
    },
    function (value) {
        console.log('setter!');
        this._val = value;
    });

    myObject.vals = ["one", "two", "three"];
    myObject.vals[1] = "five";
于 2012-06-06T17:03:29.013 回答
0

我认为timeout基于解决方案不是最好的。
如果你只能使用 push 和 pop 来修改你的数组,你可以覆盖原型的pushpop方法Array(或者只是你想要监控的一些对象):

var myWatchableArr = [];
myWatchableArr.setChangeCallback = function(callback){
    this.changeCallback = callback;
}
myWatchableArr.push = function(e){
    Array.prototype.push.call(this,e);
    if(typeof this.changeCallback == "function")
      this.changeCallback(this);
}
myWatchableArr.push(3);
myWatchableArr.setChangeCallback(function(arr){
    console.log("the array has been changed", arr);
});
// now watching for changes
myWatchableArr.push(4);

如果 push 和 pop 不够用,你可以添加一些setAt方法来使用 likemyWatchableArr.setAt(3, value)而不是myWatchableArr[3]=value.

于 2014-12-14T12:04:48.777 回答