Make an Array Reactive (Observable) 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) &gt; -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;
}
Some minor nit-picks about your code.


Object.defineProperty(array, method, {
    configurable: false,
    enumerable: false,
    writable: true,
    value: function () {
        // ...



Here, configurable and enumerable default to false anyway. You needn't set them explicitly.


if (noReturnMethods.indexOf(method) &gt; -1) {
    Array.prototype[method].apply(result, arguments);
}



With ES6, you can write the if condition more concisely as noReturnMethods.includes(method).

You could improve readability by storing ['pop','push','reverse','shift','unshift','splice','sort','map','filter'] in a variable. You could probably do

var noReturnMethods = ['push', 'pop', 'reverse', 'shift', 'unshift'];
var returnMethods = ['splice','sort','map','filter'];
var methods = [];
methods = methods.push.apply(noReturnMethods, returnMethods);


... to avoid duplication of the names of methods.

With ES6, you could do methods = [...noReturnMethods, ...returnMethods].

Assuming your environment supports ES6, you should probably make use of arrow functions and the let and const keywords.