Änderung von Objekten in ECMAScript
- Vorherige Seite Definieren Sie Klassen oder Objekte
- Nächste Seite Beispiel für das Vererbungsmechanismus
Durch die Verwendung von ECMAScript können nicht nur Objekte erstellt, sondern auch das Verhalten bestehender Objekte geändert werden.
Das Attribut 'prototype' kann nicht nur Eigenschaften und Methoden der Konstruktoren definieren, sondern auch Eigenschaften und Methoden für lokale Objekte hinzufügen.
Neue Methoden erstellen
Neue Methoden durch bestehende Methoden erstellen
Man kann mit dem prototype-Attribut neue Methoden für jede bestehende Klasse definieren, so als würde man seine eigene Klasse behandeln. Zum Beispiel, erinnern Sie sich an die Methode toString() der Klasse Number? Wenn man ihr den Parameter 16 übergibt, gibt sie eine hexadezimale Zeichenkette aus. Wenn der Parameter dieser Methode 2 ist, gibt sie eine binäre Zeichenkette aus. Man kann eine Methode erstellen, die einen numerischen Objekt direkt in eine hexadezimale Zeichenkette umwandelt. Die Erstellung dieser Methode ist sehr einfach:
Number.prototype.toHexString = function() { return this.toString(16); };
In diesem Umfeld verweist der Schlüsselwort this auf eine Instanz der Klasse Number, daher können alle Methoden der Klasse Number vollständig aufgerufen werden. Mit diesem Code können Sie die folgenden Aktionen ausführen:
var iNum = 15; alert(iNum.toHexString()); // Ausgabe "F"
Da die Zahl 15 im Hexadezimalsystem F entspricht, wird die Warnung "F" angezeigt.
Bestehende Methoden umbenennen
Sie können auch bestehende Methoden in verständlichere Namen umbenennen. Zum Beispiel können Sie der Array-Klasse die Methoden enqueue() und dequeue() hinzufügen, indem Sie nur die bestehenden Methoden push() und shift()反复 aufrufen:
Array.prototype.enqueue = function(vItem) { this.push(vItem); }; Array.prototype.dequeue = function() { return this.shift(); };
Methoden hinzufügen, die nichts mit bestehenden Methoden zu tun haben
Natürlich können Sie auch Methoden hinzufügen, die nichts mit den bestehenden Methoden zu tun haben. Zum Beispiel, wenn Sie die Position eines Elements im Array bestimmen möchten, gibt es keine lokale Methode, die dies tun kann. Sie können leicht die folgende Methode erstellen:
Array.prototype.indexOf = function (vItem) { for (var i=0; i<this.length; i++) { if (vItem == this[i]) { return i; } } return -1; }
Diese Methode indexOf() stimmt mit der gleichnamigen Methode der String-Klasse überein, sie durchsucht jedes Element im Array, bis sie das Element findet, das übereinstimmt mit dem übergebenen Element. Wenn sie ein identisches Element findet, gibt sie die Position dieses Elements zurück, andernfalls gibt sie -1 zurück. Mit dieser Definition können wir den folgenden Code schreiben:
var aColors = new Array("red","green","blue"); alert(aColors.indexOf("green")); // Ausgabe "1"
Neue Methoden für lokale Objekte hinzufügen
Wenn man eine neue Methode für jedes lokale Objekt in ECMAScript hinzufügen möchte, muss sie auf dem prototype-Attribut des Object-Objekts definiert werden. Wie in den vorherigen Kapiteln erwähnt, erben alle lokalen Objekte das Object-Objekt, daher wird jede Änderung am Object-Objekt auf alle lokalen Objekte übertragen. Zum Beispiel kann man eine Methode hinzufügen, die die aktuelle Werte des Objekts mit einer Warnung ausgibt, wie folgender Code zeigt:
Object.prototype.showValue = function () { alert(this.valueOf()); }; var str = "hello"; var iNum = 25; str.showValue(); // Ausgabe "hello" iNum.showValue(); // Ausgabe "25"
Hier haben die String- und Number-Objekte die showValue()-Methode von Object-Objekten geerbt und die Methode auf ihren Objekten aufgerufen, um "hello" und "25" anzuzeigen.
Neudefinition bestehender Methoden
Wie man neue Methoden für bestehende Klassen definieren kann, kann man auch bestehende Methoden neu definieren. Wie in den vorherigen Kapiteln beschrieben, ist der Funktionsname nur ein Zeiger auf die Funktion, daher kann er leicht auf andere Funktionen zeigen. Was passiert, wenn man lokale Methoden wie toString() ändert?
Function.prototype.toString = function() { return "Function code hidden"; }
Der obige Code ist vollkommen legal und das Ergebnis entspricht den Erwartungen:
function sayHi() { alert("hi"); } alert(sayHi.toString()); // Ausgabe "Function code hidden"
Vielleicht erinnern Sie sich noch daran, dass im Kapitel über das Function-Objekt die toString()-Methode der Function-Objekte vorgestellt wurde, die normalerweise den Quellcode der Funktion ausgibt. Durch Überschreiben dieser Methode kann eine andere Zeichenkette zurückgegeben werden (in diesem Beispiel "Function code hidden"). Was ist aber mit der ursprünglichen Funktion, die toString() zeigt? Sie wird durch den Abfallentsorgungsdienst des Systems recycelt, da sie vollständig abgelehnt wurde. Es gibt keine Möglichkeit, die ursprüngliche Funktion wiederherzustellen, daher ist es sicherer, ihren Zeiger zu speichern, falls er später benötigt wird. Manchmal kann man sogar die ursprüngliche Methode in der neuen Methode aufrufen:
Function.prototype.originalToString = Function.prototype.toString; Function.prototype.toString = function() { if (this.originalToString().length > 100) { return "Funktion zu lang zum Anzeigen."; } else { return this.originalToString(); } };
In diesem Code speichert die erste Zeile eine Referenz auf die aktuelle toString()-Methode im Attribut originalToString. Dann wird die toString()-Methode durch eine benutzerdefinierte Methode ersetzt. Die neue Methode überprüft, ob die Länge des Quellcodes der Funktion länger als 100 Zeichen ist. Wenn ja, wird eine Fehlermeldung zurückgegeben, die besagt, dass der Quellcode der Funktion zu lang ist, andernfalls wird die Methode originalToString() aufgerufen und der Quellcode der Funktion zurückgegeben.
Späte Bindung (Very Late Binding)
Technisch gesehen gibt es keine späte Bindung. Dieses Buch verwendet diesen Begriff, um ein Phänomen in ECMAScript zu beschreiben, bei dem Methoden nach der Instanziierung eines Objekts definiert werden können. Zum Beispiel:
var o = new Object(); Object.prototype.sayHi = function () { alert("hi"); }; o.sayHi();
In den meisten Programmiersprachen muss vor der Instanziierung eines Objekts die Methode des Objekts definiert werden. Hier wird die Methode sayHi() nach der Erstellung eines Instanzes der Klasse Object hinzugefügt. In traditionellen Sprachen wurde solche Operation nicht gehört und auch nicht, dass diese Methode automatisch dem Objektinstanz des Objects zugewiesen wird und sofort verwendet werden kann (im nächsten Zeilen).
Hinweis:Es wird nicht empfohlen, Methoden der späten Bindung zu verwenden, da sie schwer zu verfolgen und zu protokollieren sind. Es sollte jedoch verstanden werden, dass dies möglich ist.
- Vorherige Seite Definieren Sie Klassen oder Objekte
- Nächste Seite Beispiel für das Vererbungsmechanismus