web-dev-qa-db-fra.com

Comment étendre Array.prototype.Push ()?

J'essaie d'étendre la méthode Array.Push de sorte que l'utilisation de Push déclenche une méthode de rappel, puis exécute la fonction array normale.

Je ne sais pas trop comment faire cela, mais voici un code avec lequel j'ai joué sans succès.

arr = [];
arr.Push = function(data){

    //callback method goes here

    this = Array.Push(data);
    return this.length;

}

arr.Push('test');
27
Geuis

Comme Push permet de pousser plus d’un élément, j’utilise la variable arguments ci-dessous pour permettre à la méthode Push réelle d’avoir tous les arguments.

Cette solution n'affecte que la variable arr:

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

Cette solution affecte tous les tableaux. Je ne vous recommande pas de le faire.

Array.prototype.Push=(function(){
    var original = Array.prototype.Push;
    return function() {
        //Do what you want here.
        return original.apply(this,arguments);
    };
})();
69
some

Vous avez d’abord besoin de la sous-classe Array:

ES6: (non compatible avec Babel ou les navigateurs autres que Chrome50 + actuellement https://kangax.github.io/compat-table/es6/ )

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

es5: ( proto est presque obsolète, mais c'est la seule solution pour l'instant)

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);
};
7
codepig

Array.prototype.Push a été introduit dans JavaScript 1.2. C'est vraiment aussi simple que ça:

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

Vous pouvez toujours ajouter quelque chose à l'avant de cela.

6
Jhuni

Vous pouvez le faire de cette façon:

arr = []
arr.Push = function(data) {
  alert(data); //callback

  return Array.prototype.Push.call(this, data);
}

Si vous êtes dans une situation sans appel, vous pouvez également opter pour cette 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;
}

Modifier:

Bien que je vous dise comment faire, vous feriez peut-être mieux d'utiliser une méthode différente qui effectue le rappel, puis appelez simplement Push sur le tableau plutôt que de remplacer Push. Vous pouvez vous retrouver avec des effets secondaires inattendus. Par exemple, Push semble être varadic (prend un nombre variable d'arguments, comme printf), et utiliser ce qui précède briserait cela.

Vous aurez besoin de déconner avec _Arguments () et _ArgumentsLength () pour redéfinir correctement cette fonction. Je suggère fortement contre cette voie. 

Editez une fois de plus: Ou vous pouvez utiliser "arguments", cela fonctionnerait aussi. Déconseillez toujours de prendre cette voie cependant.

5
Patrick

Je voulais appeler une fonction after l'objet a été placé dans le tableau. J'ai donc procédé comme suit:

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
Felipe Carminati