Właściwość prototype w JavaScript
Próbując podejść do tematu obiektowości w JavaScripcie musisz niejako zapomnieć o filozofii znanej z języków takich jak Java czy C# i zapoznać się z tematem na nowo. Oczywiście, wszelkie zasady programowania zorientowanego obiektowo występują także i tutaj, jednak forma prezentacji daleka jest od tego, do czego przyzwyczaiły nas inne języki. Tutaj jako bohater pierwszoplanowy jawi się właściwość prototype, budząca skrajne emocje wśród osób, które miały z nią do czynienia: jedni jej nienawidzą, inni uznają za wynaturzenie, a jeszcze inni kochają za to, że w ogóle istnieje.
Trochę teorii
W JavaScript wszystko to, co nie jest typem prymitywnym (undefined, null, boolean, number oraz string*) jest obiektem. Każdy obiekt posiada właściwość prototype, która również jest obiektem. Prototype pozwala rozszerzyć definicję klasy** o nowe metody oraz pola, także w predefiniowanych klasach, takich jak String, Date czy Array. W ten sposób JavaScript zyskuje mechanizmy, które z jednej strony pozwalają na tworzenie kodu obiektowego, a z drugiej – na rozbudowę kluczowych dla języka klas predefiniowanych.
* W JavaScript string występuje zarówno jako typ prymitywny (string literal) oraz jako obiekt (String object).
** Słowo „klasa” jest tu trochę naciągane. JavaScript nie posiada klas, a jedynie bazujący na prototype model dziedziczenia. Mimo to JavaScript jest określany jako zorientowany obiektowo (OOP) ze względu na istnienie dziedziczenia, enkapsulacji oraz polimorfizmu (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript).
Przykład 1: prototype dla obiektu typu String
String.prototype.startsWith = function (str) {
return this.indexOf(str) === 0;
}
if ("prototype".startsWith("pro")) {
document.write("Wyraz prototype zaczyna się od pro");
}
Wynik:
Przykład 2: prototype dla obiektu typu Array
Poniższy kod dodaje do obiektu Array metodę avg(), która zwraca średnią arytmetyczną elementów tej tablicy (przy założeniu, że elementy są liczbami).
function arrayGetAvg() {
var sum = 0;
var count = this.length;
for (var i = 0; i < this.length; i++)
{
sum += this[i];
}
return (sum/count);
}
Array.prototype.avg = arrayGetAvg;
var myArray = new Array(1, 31, 53, 14, 45);
document.write(myArray.avg());
Wynik:
Więcej informacji