Obiekty JavaScript to kontenery dla nazwanych wartości, zwanych właściwościami i metodami. W JS prawie wszystko jest obiektem:
Prymitywna wartość jest to wartość, która ma właściwości lub metody.
Prymitywny typ danych to dane, które posiadają pierwotną wartość.
JavaScript definiuje 5 typów prymitywnych typów danych:
Obiekty są zmiennymi, ale mogą zawierać wiele wartości.
Wartości są zapisywane jako pary nazwa: wartość (nazwa i wartość oddzielone dwukropkiem). Pary te oddziela przecinek.
Obiekt JavaScript to zbiór nazwanych wartości. Te nazwane wartości nazywamy właściwościami.
var osoba = { imie: "Piotr", nazwisko: "Zalewski", wiek: 44, kolorOczu: "niebieski" };
Mamy tu 4 właściwości obiektu
osoba
: imie, nazwisko, wiek, kolorOczu.Właściwościami obiektów mogą być zarówno prymitywne wartości, inne obiekty, jak i funkcje.
objectName.property // np. osoba.imie; objectName["property"] // np. osoba["imie"]; objectName[expression] // np. i="imie"; osoba(i);Zebranie i wyświetlenie wartości własności za pomocą pętli for... in
var info = ""; var osoba = {imie: "Piotr", nazwisko: "Zalewski", wiek: 44, kolorOczu: "niebieski"}; for (x in osoba) { info += osoba[x] + " "; } alert(info); //zwróci: Piotr Zalewski 44 niebieskiDopisanie nowych wartości albo właściwości:
osoba.wiek=33; //zmiana wartości własności osoba.wzrost= 183; // dopisanie nowej własnościUsuwanie własności (delete):
delete osoba.wiek;
Obiekty JavaScript dziedziczą właściwości ich prototypu. Słowo kluczowe delete nie usuwa odziedziczonych właściwości, ale usunięcie właściwości prototypu wpłynie na wszystkie obiekty odziedziczone z prototypu.
podpis: function () {return this.imie + " " + this.nazwisko;}cały obiekt (5 właściwości, w tym 1 metoda):
var osoba = { imie: "Piotr", nazwisko: "Zalewski", wiek: 44, kolorOczu: "niebieski", podpis: function () {return this.imie + " " + this.nazwisko;} };This. W definicji funkcji this odnosi się do „właściciela” funkcji. Czyli w powyższej definicji 'this' to 'podpis'.
objectName.methodName()Dostęp do właściwości bez (), zwróci definicję funkcji.
"Ala".toUpperCase()Dodawanie metody do istniejącego obiektu:
osoba.pseudonim = function () { return this.imie + "" + this.wiek;};
new
(zdefiniowanie i utwórzenie pojedynczego obiektu)Najprostszy sposób na utworzenie pojedynczego obiektu JavaScript. Używając literału obiektu, zarówno definiujesz, jak i tworzysz obiekt w jednej instrukcji. Literał obiektu to lista par nazwa: wartość w nawiasach klamrowych {}.
var osoba = {imie: "Piotr", nazwisko: "Zalewski", wiek: 44, kolorOczu: "niebieski"};lub ładniej, w wielu liniach (spacje i podziały linii nie są ważne w JS):
var osoba = { imie: "Piotr", nazwisko: "Zalewski", wiek: 44, kolorOczu: "niebieski" };
var osoba = new Object();i po utworzeniu obiektu tworzymy jego właściwości:
osoba.imie="Piotr"; osoba.nazwisko="Zalewski"; osoba.wiek=44; osoba.kolorOczu="niebieski";1 i 2 robią dokładnie to samo. Dla prostoty, czytelności i szybkości lepiej użyć 1.
var osoba = {imie: "Piotr", nazwisko: "Zalewski", wiek: 44, kolorOczu: "niebieski"}; var tablica=Object.values(osoba); alert(tablica); // zwróci: Piotr,Zalewski,44,niebieskiInnym sposobem konwersji obiektu, tym razem na łańcuch jest JSON.stringify(obiekt)
var osoba = {imie: "Piotr", nazwisko: "Zalewski", wiek: 44, kolorOczu: "niebieski"}; var tekst=Object.values(osoba); alert(tekst); //zwróci: {"imie":"Piotr","nazwisko":"Zalewski","wiek":44,"kolorOczu":"niebieski"} //(notyfikacja JSON)Ponieważ JSON.stringify() nie przekształci metod to należałoby te metody przekształcić wcześniej na tekst poprzez
osoba.pseudonim = osoba.pseudonim.toString();
Możesz zdefiniować metody pobierające (metody dostępu) i ustawiające (metody mutatora) w dowolnym standardowym obiekcie wbudowanym lub obiekcie zdefiniowanym przez użytkownika, który obsługuje dodawanie nowych właściwości. Składnia do definiowania modułów pobierających i ustawiających używa składni literału obiektu.
get - wiąże właściwość obiektu z funkcją, która zostanie wywołana podczas wyszukiwania tej właściwości.
Składnia:{get prop() { ... } } {get [expression]() { ... } }gdzie prop to nazwa właściwości, która łączy ją z okresloną funkcją.
Getter umożliwia dostęp do właściwości, która zwraca wartość obliczaną dynamicznie lub odzwierciedla stan jakiejś wewnętrznej zmiennej bez potrzeby użycia wyraźnego wywołania metody. Połączenia gettera i settera tworzy rodzaj pseudo-właściwości.
Gettery dają ci możliwośc zdefiniowania właściwości obiektu, ale nie obliczają wartości właściwości dopóki nie jest ona dostępna. Getter odracza koszt obliczania wartości dopóki ta wartość jest potrzebna, a jeśli nigdy nie jest potrzebna, nie ponosi się tego kosztu.
Dodatkową techniką optymalizacyjna aby uleniwić lub opóźnić obliczanie wartości dla właściwości jak i przechować ją na później są bystre (smart) lub zmemoizowane gettery. Wartość jest obliczana gdy getter jest wywoływany za pierwszym razem, a potem jest przechowywana więc kolejne dostępy zwracają zbuforowaną wartość bez jej ponownego obliczania.
Getter może być usunięty za pomocą delete.
set - wiąże właściwość obiektu z funkcją, która ma zostać wywołana, gdy nastąpi próba ustawienia tej właściwości.
Składnia:{set prop(val) { . . . }} {set [expression](val) { . . . }}
gdzie prop to nazwa właściwości, która łączy ją z okresloną funkcją.
a val to alias zmiennej, która zawiera wartość, którą próbujemy przypisać
Porównajmy funkcję (metodę) z getterem i seterem:
Metoda:
var osoba = { imie: "Piotr", nazwisko: "Zalewski", wiek: 44, kolorOczu: "niebieski", podpis: function () {return this.imie + " " + this.nazwisko;} }; alert(osoba.podpis()); //dostęp przez funkcjęGetter
var osoba = { imie: "Piotr", nazwisko: "Zalewski", wiek: 44, kolorOczu: "niebieski", get podpis() {return this.imie + " " + this.nazwisko;} //prostsza składnia }; alert(osoba.podpis); // dostęp przez właściwość - bez ()Seter
var osoba = { imie: "Piotr", nazwisko: "Zalewski", wiek: 44, kolorOczu: "niebieski", kraj: "", get podpis() {return this.imie + " " + this.nazwisko}, set skrotKraj(skrotKraj) {this.kraj = skrotKraj.toUpperCase()} }; osoba.skrotKraj= "pl"; // używamy settera alert(osoba.podpis +" "+ osoba.kraj);
var licznik = {counter : 0}; Object.defineProperty(licznik, "reset", { get : function () {this.counter = 0;} }); Object.defineProperty(licznik, "increment", { get : function () {this.counter++;} }); Object.defineProperty(licznik, "add", { set : function (value) {this.counter += value;} }); Object.defineProperty(licznik, "subtract", { set : function (value) {this.counter -= value;} }); licznik.reset; licznik.add = 5; licznik.subtract = 2; licznik.increment; alert(licznik.counter);
Jeśli potrzebujemy wielu obiektów tego samego „typu” warto użyć funkcji konstruktora obiektów. Obiekty tego samego typu są tworzone przez wywołanie funkcji konstruktora za pomocą słowa kluczowego new. Dobrą praktyką jest nazywanie funkcji konstruktora wielką pierwszą literą.
function Osoba(imie, nazwisko, wiek, kolor) { this.imie = imie; this.nazwisko = nazwisko; this.wiek = wiek; this.kolorOczu = kolor; this.narodowosc = "Polak"; //wartość domyślna } var ojciec = new Person("Piotr", "Kowalski", 30, "niebieski"); var ciocia = new Person("Halina", "Miszko", 35, "czarny");
W funkcji konstruktora this nie ma wartości. Jest substytutem nowego obiektu. Wartość this zostanie zmieniona na obiekt po jego utworzeniu.
this to nie jest zmienna tylko słowo kluczowe. Nie można zmienić wartości this.
Nie można dodać nowej właściwości do konstruktora obiektów w taki sam sposób, jak dodaje się nową właściwość do istniejącego obiektu. Aby dodać nową właściwość do konstruktora, musisz dodać ją do funkcji konstruktora.
W funkcji konstruktora możesz też zdefiniować metody:
... this.podpis = function() {return this.imie + " " + this.nazwisko;}; ...
var o = new Object(); // nowy obiekt Object var s = new String(); // nowy obiekt String var n = new Number(); // nowy obiekt Number var b = new Boolean(); // nowy obiekt Boolean var a = new Array(); // nowy obiekt Array var r = new RegExp(); // nowy obiekt RegExp var f = new Function(); // nowy obiekt Function var d = new Date(); // nowy obiekt DateObiekt Math() nie znajduje się na liście, jest obiektem globalnym. Nie można użyć słowa kluczowego new Math.
var o = {}; // object var s = ""; // primitive string var n = 0; // primitive number var b = false; // primitive boolean var a = []; // object (array) var r = /()/ ; // object (regexp) var f = function(){}; // function object
Wszystkie obiekty JavaScript dziedziczą właściwości i metody z prototypu.
- obiekty Date dziedziczą po Date.prototype
- obiekty Array dziedziczą po Array.prototype
- obiekty Osoba dziedziczą po Person.prototype
Wszytkie obiekty dziedziczą po Object.prototype
Właściwość prototype pozwala dodawać nowe właściwości i metody do konstruktorów obiektów!
Modyfikuj tylko własne prototypy. Nigdy nie modyfikuj prototypów standardowych obiektów JavaScript.
function Osoba(imie, nazwisko, wiek, kolor) { this.imie = imie; this.nazwisko = nazwisko; this.wiek = wiek; this.kolorOczu = kolor; } Osoba.prototype.narodowosc = "Polak"; Osoba.prototype.podpis = function() { return this.imie + " " + this.nazwisko; }; var ja = new Osoba("Piotr", "Ja", 99, "piwny"); alert(ja.imie+" "+ja.narodowosc); //zwróci Piotr Polak