有没有办法在数组项值更改时获得回调?

时间:2012-06-06 15:40:24

标签: javascript javascript-events cross-browser

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

变量更改时定义了一些问题(定义getter或setter)。似乎有a way to do that(至少对于包括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()函数来访问/修改数据。

3 个答案:

答案 0 :(得分:3)

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

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

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

但是这种方法有一些明显的问题:它会进行民意调查,观看一堆数组会变得很慢等等。

答案 1 :(得分: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";

答案 2 :(得分:0)

我认为基于timeout的解决方案并不是最好的 如果您只能使用push和pop来修改数组,则可以覆盖push原型的popArray方法(或仅限某些要监视的对象):

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);

如果推送和弹出功能不足,您可以添加一些setAt方法,例如myWatchableArr.setAt(3, value)而不是myWatchableArr[3]=value