Comment étendre Array.prototype.push ()?

J'essaie d'étendre la méthode Array.push pour que l'utilisation de push déclenche une méthode de rappel, puis effectuez la fonction de tableau normal.

Je ne sais pas trop comment faire, 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'); 

Puisque la poussée permet de pousser plus d'un élément, j'utilise la variable d'arguments ci-dessous pour que la méthode de la pression réelle comporte 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); }; })(); 

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 en situation sans appel, vous pouvez également utiliser 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 le faire, vous pourriez être mieux servi avec l'utilisation d'une méthode différente qui effectue le rappel, puis appelle push sur le tableau plutôt que de repousser push. Vous pouvez vous retrouver avec des effets secondaires inattendus. Par exemple, la pression semble être varadic (prend un nombre variable d'arguments, comme printf), et l'utilisation de ce qui précède casserait cela.

Vous devriez faire du filetage avec _Arguments () et _ArgumentsLength () pour remplacer correctement cette fonction. Je suggère fortement cette route.

Éditez une fois de plus: ou vous pouvez utiliser des "arguments", cela fonctionnerait aussi. Toujours conseiller de ne pas emprunter cette route.

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

 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.

Je voulais appeler une fonction après que l'objet a été poussé sur le tableau, alors j'ai fait ce qui 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; } } 

D'abord vous avez besoin de la sous-classe Array :

ES6: (pas compatible avec babel ou un navigateur autre que Chrome50 + dès maintenant 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); }; 

Je ferais ceci:

 var callback = function() { alert("called"); }; var original = Array.prototype.push; Array.prototype.push = function() { callback(); return original.apply(this, arguments); }; 

Si vous vouliez qu'un argument soit un rappel, vous pouvez le faire:

 var original = Array.prototype.push; Array.prototype.push = function(callback) { callback(); return original.apply(this, Array.prototype.slice.call(arguments, 1)); } 

Ces deux tests ont été testés.