If it is critical to know when a value has changed you would need to create explicit setters and getters.
As suggested Proxy is a good option if available. It may not be available to in all browsers though. In this case you could create a new object that notifies you when it was set.
There a lot of trade offs with this approach, and it would be a fair amount of work to implement everything array natively provides. The example below is pretty bare-bones but it does provide array like interactions and a setter event to listen to.
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());
If you only needed a way to be able to make something happen when an array value is set, you could extend the array to have a set method that fires a callback. It would be up to the programmer to use it though.
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);
});