34 Stimmen

Wie kann ich Array.prototype.push() erweitern?

Ich versuche, die Array.push Methode, so dass die Verwendung von push eine Callback-Methode auslöst und dann die normale Array-Funktion ausführt.

Ich bin mir nicht ganz sicher, wie man das macht, aber hier ist ein Code, mit dem ich erfolglos gespielt habe.

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

    //callback method goes here

    this = Array.push(data);
    return this.length;
}

arr.push('test');

78voto

some Punkte 45857

から drücken. mehr als ein Element geschoben werden kann, verwende ich die Argumente Variable unten, damit die eigentliche Push-Methode alle Argumente hat.

Diese Lösung betrifft nur die arr variabel:

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

Diese Lösung betrifft alle Arrays. Ich empfehle nicht, dass Sie das tun.

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

0 Stimmen

Meine bevorzugte Form des Funktions-Wrappings ist die Übergabe von Array.prototype.push bei der Ausführung der äußeren Funktion und die Übernahme in die Funktion als ursprüngliche Variable. Das ist ein wenig prägnanter

9 Stimmen

@pottedmeat: aber es ist weniger lesbar - bedenken Sie, dass Programme nicht nur für die Maschine geschrieben werden, sondern auch für andere Programmierer!

1 Stimmen

@some Vielen Dank für die klare Erläuterung von Prototyp und nicht!

11voto

codepig Punkte 531

Zuerst müssen Sie die Unterklasse Array :

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

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

ES5 ( proto ist fast veraltet, aber es ist die einzige Lösung für jetzt):

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

8 Stimmen

Warum sollte man das nicht tun? JS hat sich verändert.

6voto

Patrick Punkte 86090

Sie könnten es so machen:

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

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

Wenn Sie sich in einer Situation befinden, in der Sie nicht angerufen werden können, können Sie sich auch für diese Lösung entscheiden:

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

Während ich Ihnen erkläre, wie man es macht, sind Sie vielleicht besser bedient, wenn Sie eine andere Methode verwenden, die den Rückruf durchführt und dann einfach aufruft drücken. auf das Array anzuwenden, anstatt die drücken. . Es kann zu unerwarteten Nebenwirkungen kommen. Zum Beispiel, drücken. scheint varadisch zu sein (nimmt eine variable Anzahl von Argumenten an, wie printf ), und die Verwendung der oben genannten Methode würde das verhindern.

Sie müssten mit _Arguments() und _ArgumentsLength() herumspielen, um diese Funktion richtig zu überschreiben. Ich empfehle dringend gegen diese Route.

Oder Sie könnten "Argumente" verwenden, das würde auch funktionieren. Ich rate aber trotzdem davon ab, diesen Weg zu gehen.

0 Stimmen

Array.prototype.push.call(this, data); wird nicht funktionieren, da Array mehrere Elemente aufnehmen kann. Array.prototype.push.apply(this, arguments);

6voto

Array.prototype.push wurde in JavaScript 1.2 eingeführt. Es ist wirklich so einfach wie dieses:

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

Man könnte immer etwas davor setzen.

1voto

shaedrich Punkte 4845

Es gibt noch eine andere, ursprünglichere Methode, dies zu erreichen: 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);

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X