ECMAScript Object Wijzigen
- Vorige pagina Definieer een klasse of object
- Volgende pagina Voorbeeld van hetheirlijke mechanisme
Met het gebruik van ECMAScript kunnen niet alleen objecten worden gemaakt, maar ook het gedrag van bestaande objecten worden gewijzigd.
Het prototype-eigenschap kan niet alleen de eigenschappen en methoden van de constructor definiëren, maar ook eigenschappen en methoden toevoegen aan lokale objecten.
Maak nieuwe methoden
Maak nieuwe methoden met bestaande methoden
Je kunt met de prototype-eigenschap nieuwe methoden definiëren voor elke bestaande klasse, net alsof je je eigen klasse behandelt. Bijvoorbeeld, herinner je je aan de toString()-methode van de Number-klasse? Als je 16 als parameter naar deze methode stuurt, geeft het een hexadecimale string weer. Als de parameter 2 is, geeft het een binair string weer. We kunnen een methode maken die een getalobject direct omzet in een hexadecimale string. Dit is zeer eenvoudig:
Number.prototype.toHexString = function() { return this.toString(16); };
In deze omgeving wijst de sleutelwoord this volledig naar een Number-instantie, waardoor alle methoden van Number volledig toegankelijk zijn. Met deze code kun je de volgende actie uitvoeren:
var iNum = 15; alert(iNum.toHexString()); //Output "F"
Omdat het getal 15 gelijk is aan F in het hexadecimaal, wordt de waarschuwing weergegeven als "F".
Hernoem bestaande methoden
We kunnen ook bestaande methoden hernoemen om ze begrijpelijker te maken. Bijvoorbeeld, we kunnen de Array-klasse de methoden enqueue() en dequeue() toevoegen, zodat ze alleen de bestaande methoden push() en shift() aanroepen:
Array.prototype.enqueue = function(vItem) { this.push(vItem); }; Array.prototype.dequeue = function() { return this.shift(); };
Voeg methoden toe die niet betrokken zijn bij bestaande methoden
Natuurlijk, je kunt ook methoden toevoegen die niet betrokken zijn bij bestaande methoden. Bijvoorbeeld, als je wilt bepalen op welke positie een item in de array staat, is er geen lokaal method dat dit kan doen. We kunnen gemakkelijk de volgende methode maken:
Array.prototype.indexOf = function (vItem) { for (var i=0; i<this.length; i++) { if (vItem == this[i]) { return i; } } return -1; }
De methode indexOf() is consistent met de naamgenote methode van de String-klasse, die elk item in de array doorzoekt totdat het een item vindt dat overeenkomt met het binnengebrachte item. Als het een overeenkomstig item vindt, retourneert het de positie van dat item, anders retourneert het -1. Met deze definitie kunnen we de volgende code schrijven:
var aColors = new Array("red","green","blue"); alert(aColors.indexOf("green")); //Uitvoer: "1"
Nieuwe methoden toevoegen aan lokale objecten
Ten slotte, om een nieuwe methode toe te voegen aan elk lokaal object in ECMAScript, moet deze worden gedefinieerd op het prototype-eigenschap van het Object-object. Zoals eerder in het hoofdstuk is besproken, erven alle lokale objecten het Object-object, dus elke wijziging in het Object-object heeft een effect op alle lokale objecten. Bijvoorbeeld, als je een methode wilt toevoegen die de huidige waarde van het object met een waarschuwing uitgeeft, kun je de volgende code gebruiken:
Object.prototype.showValue = function () { alert(this.valueOf()); }; var str = "hello"; var iNum = 25; str.showValue(); //Uitvoer: "hello" iNum.showValue(); //Uitvoer: "25"
Hierin hebben de String- en Number-objecten de showValue() methode geërfd van het Object-object, en wanneer deze methode op hun objecten wordt aangeroepen, wordt "hello" en "25" weergegeven.
Herdefiniëren van bestaande methoden
Net als je nieuwe methoden kunt definiëren voor bestaande klassen, kun je bestaande methoden ook opnieuw definiëren. Zoals eerder in het hoofdstuk is besproken, is de functienaam een verwijzing naar de functie, dus je kunt gemakkelijk naar een andere functie wijzen. Wat gebeurt er als je een lokale methode, zoals toString(), aanpast?
Function.prototype.toString = function() { return "Function code hidden"; }
Deze code is volledig legaal en het resultaat voldoet aan de verwachtingen:
function sayHi() { alert("hi"); } alert(sayHi.toString()); //Uitvoer: "Function code hidden"
Misschien herinner je je nog, in het hoofdstuk over Function object is de toString() methode van Function besproken, die meestal de broncode van de functie uitgeeft. Door deze methode over te schrijven, kan een andere string worden geretourneerd (in dit voorbeeld kan dat "Function code hidden" zijn). Wat is er echter gebeurd met de oorspronkelijke functie waar toString() naartoe wijst? Hij zal worden opgeruimd door het programma voor het recyclen van onnodige opslagruimte, omdat hij volledig is afgekeurd. Er is geen manier om de oorspronkelijke functie te herstellen, dus het is veiliger om zijn pointer op te slaan voordat je de oorspronkelijke methode overschrijft, zodat je hem later kunt gebruiken. Soms kun je zelfs de oorspronkelijke methode aanroepen in de nieuwe methode:
Function.prototype.originalToString = Function.prototype.toString; Function.prototype.toString = function() { if (this.originalToString().length > 100) { return "Functie te lang om weer te geven."; } else { return this.originalToString(); } };
In deze code bewaart de eerste regel de referentie naar de huidige toString() methode in de eigenschap originalToString. Vervolgens overschrijft de aangepaste methode de toString() methode. De nieuwe methode controleert of de lengte van de broncode van de functie groter is dan 100. Als dat zo is, retourneert het een foutbericht dat de functiecode te lang is, anders roept het de methode originalToString() aan en retourneert het de broncode van de functie.
Veer late binding (Very Late Binding)
Technisch gezien bestaat er geen zeer late binding. Dit boek gebruikt dit termijn om een fenomeen in ECMAScript te beschrijven, waarbij het mogelijk is om na het instantiëren van een object zijn methoden te definiëren. Bijvoorbeeld:
var o = new Object(); Object.prototype.sayHi = function () { alert("hi"); }; o.sayHi();
In de meeste programmeertalen moet de methode van het object worden gedefinieerd voordat het object geïntanceerd wordt. Hier wordt de methode sayHi() toegevoegd nadat een instance van de Object-klasse is gecreëerd. In traditionele talen is deze actie niet bekend en ook niet dat deze methode automatisch de instance van het Object-object toekent en deze onmiddellijk kan gebruiken (in de volgende regel).
Let op:Het wordt niet aanbevolen om zeer late binding-methode te gebruiken, omdat het moeilijk is om deze te volgen en te registreren. Toch zou men deze mogelijkheid moeten begrijpen.
- Vorige pagina Definieer een klasse of object
- Volgende pagina Voorbeeld van hetheirlijke mechanisme