这可能看起来很愚蠢,但是在这个时代,如果数组的内容发生了变化,那么应该能够期望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()函数来访问/修改数据。
答案 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
原型的pop
和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);
如果推送和弹出功能不足,您可以添加一些setAt
方法,例如myWatchableArr.setAt(3, value)
而不是myWatchableArr[3]=value
。