I have written a simple JavaScript function to make an array reactive (i.e. observable). Is there anything I could improve? What the code does is take an array, a callback and a this
value as arguments, then whenever the array gets updated or a value gets added to it, it runs the callback with the specified this
value. It works similar to the obsolete Array.observe()
.
function arrayObserve(array, callback, thisArg){
var result = [];
result.push.apply(result, array);
function getterAndSetter() {
if (Array.isArray(array))
var currentArray = result;
else
var currentArray = Object.keys(result);
console.log(result);
currentArray.forEach( function(prop){
if (Array.isArray(result))
var currentProp = result.lastIndexOf(prop);
else
var currentProp = prop;
Object.defineProperty(array, currentProp, {
configurable: true,
enumerable: true,
set: function(val) {
result[currentProp] = val;
callback.call(thisArg, result);
},
get: function() {
return result[currentProp];
}
});
//}
if (typeof result[currentProp] == 'object') {
arrayObserve(result[currentProp], callback, result);
}
});
}
getterAndSetter();
['pop','push','reverse','shift','unshift','splice','sort','map','filter'].forEach( function(method){
Object.defineProperty(array, method, {
configurable: false,
enumerable: false,
writable: true,
value: function () {
var noReturnMethods = ['push', 'pop', 'reverse', 'shift', 'unshift'];
if (noReturnMethods.indexOf(method) > -1) {
Array.prototype[method].apply(result, arguments);
} else {
var results = Array.prototype[method].apply(result, arguments);
result = results;
}
callback.call(thisArg, result);
getterAndSetter();
return result;
}
});
});
return result;
}