How to extend Array.prototype.push()?

后端 未结 6 676
遥遥无期
遥遥无期 2020-11-27 02:45

I\'m trying to extend the Array.push method so that using push will trigger a callback method, then perform the normal array function.

I\'m not quite sure how to do

相关标签:
6条回答
  • 2020-11-27 03:10

    I wanted to call a function after the object has been pushed to the array, so I did the following:

    myArray.push = function() { 
        Array.prototype.push.apply(this, arguments);
        myFunction();
        return myArray.length;
    };
    
    function myFunction() {
        for (var i = 0; i < myArray.length; i++) {
            //doSomething;
        }
    }
    
    0 讨论(0)
  • 2020-11-27 03:18

    Since push allows more than one element to be pushed, I use the arguments variable below to let the real push method have all arguments.

    This solution only affects the arr variable:

    arr.push = function (){
        //Do what you want here...
        return Array.prototype.push.apply(this,arguments);
    }
    

    This solution affects all arrays. I do not recommend that you do that.

    Array.prototype.push=(function(){
        var original = Array.prototype.push;
        return function() {
            //Do what you want here.
            return original.apply(this,arguments);
        };
    })();
    
    0 讨论(0)
  • 2020-11-27 03:22

    Array.prototype.push was introduced in JavaScript 1.2. It is really as simple as this:

    Array.prototype.push = function() {
        for( var i = 0, l = arguments.length; i < l; i++ ) this[this.length] = arguments[i];
        return this.length;
    };
    

    You could always add something in the front of that.

    0 讨论(0)
  • 2020-11-27 03:29

    First you need subclass Array:

    ES6 (https://kangax.github.io/compat-table/es6/):

    class SortedArray extends Array {
        constructor(...args) {
            super(...args);
        }
        push() {
            return super.push(arguments);
        }
    }
    

    es5:(proto is almost deprecated but it is the only solution for now)

    function SortedArray() {
        var arr = [];
        arr.push.apply(arr, arguments);
        arr.__proto__ = SortedArray.prototype;
        return arr;
    }
    SortedArray.prototype = Object.create(Array.prototype);
    
    SortedArray.prototype.push = function() {
        this.arr.push(arguments);
    };
    
    0 讨论(0)
  • 2020-11-27 03:32

    You could do it this way:

    arr = []
    arr.push = function(data) {
      alert(data); //callback
    
      return Array.prototype.push.call(this, data);
    }
    

    If you're in a situation without call, you could also go for this solution:

    arr.push = function(data) {
      alert(data); //callback
    
      //While unlikely, someone may be using psh to store something important
      //So we save it.
      var saved = this.psh;
      this.psh = Array.prototype.push;
      var ret = this.psh(data);
      this.psh = saved;
      return ret;
    }
    

    Edit:

    While I'm telling you how to do it, you might be better served with using a different method that performs the callback then just calls push on the array rather than overriding push. You may end up with some unexpected side effects. For instance, push appears to be varadic (takes a variable number of arguments, like printf), and using the above would break that.

    You'd need to do mess with _Arguments() and _ArgumentsLength() to properly override this function. I highly suggest against this route.

    Edit once more: Or you could use "arguments", that'd work too. Still advise against taking this route though.

    0 讨论(0)
  • 2020-11-27 03:32

    The question is old, but for those who'll find this question nowadays, there's another, more native method to achieve this: Proxy

    const target = [];
    
    const handler = {
      set: function(array, index, value) {
        // call callback function here
    
        // The default behavior to store the value
        array[index] = value;
    
        // Indicate success
        return true;
      }
    };
    
    const proxyArray = new Proxy(target, handler);
    
    0 讨论(0)
提交回复
热议问题