如果知道值何时发生变化很重要,您将需要创建显式的 setter 和 getter。
正如建议的那样,如果可用,代理是一个不错的选择。但是,它可能不适用于所有浏览器。在这种情况下,您可以创建一个新对象,在设置时通知您。
这种方法有很多折衷,要实现数组本机提供的所有内容将是相当多的工作。下面的示例非常简单,但它确实提供了类似数组的交互和一个要监听的 setter 事件。
var observableArray = function(eventName) {
var myArray = [];
var api = {};
api.get = function(index) {
if (myArray.length && typeof index === 'number') {
return myArray[index];
}
};
api.set = function(item, index) {
if (typeof index === 'number') {
myArray[index] = item;
}
else {
index = myArray.push(item) - 1;
}
var event = new CustomEvent(eventName, {detail: index});
document.dispatchEvent(event);
return index;
};
api.getLength = function() {
return myArray.length;
};
api.empty = function() {
myArray.splice(0, myArray.length);
};
return api;
};
var arrayListener = document.addEventListener('foo', function(e) {console.log('The index modified: ',e.detail);},false);
var test = new observableArray('foo');
test.set('bar');
console.log('The # of items: ', test.getLength());
test.empty();
console.log('The # of items after empty: ', test.getLength());
如果您只需要一种能够在设置数组值时发生某些事情的方法,您可以扩展数组以具有触发回调的 set 方法。不过,这将取决于程序员使用它。
Array.prototype.set = function(item, index, callback) {
if (typeof index === 'number') {
this[index] = item;
}
else {
index = this.push(item) - 1;
}
if (callback) {
callback.apply(this, [index]);
}
return index;
};
var test2 = [];
test2.set('foo', 4, function(i) {
console.log('Callback value: ', i);
console.log('The array: ', this);
});