JavaScript - obiekty. Object.


Typ object

Obiekty JavaScript to kontenery dla nazwanych wartości, zwanych właściwościami i metodami. W JS prawie wszystko jest obiektem:

Wszystkie wartości JavaScript, z wyjątkiem prymitywów (primitives), są obiektami.

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:

Wartości pierwotne są niezmienne (są zakodowane na stałe i dlatego nie można ich zmienić).

Właściwości obiektu.

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.

Dostęp do właściwości. Pętla for... in. Dodawanie, usuwanie własności.

Składnia dostępu do właściwości jest następująca:
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
musimy tu użyć osoba[właściwość] a nie osoba.właściwość ponieważ x jest zmienną
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 niebieski 
Dopisanie nowych wartości albo właściwości:
osoba.wiek=33;           //zmiana wartości własności
osoba.wzrost= 183;    // dopisanie nowej własności
Usuwanie 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.

Metody obiektu

Metody JavaScript to akcje, które można wykonywać na obiektach. Metodą obiektu nazywamy właściwość zawierającą definicję funkcji (inaczej: metoda to funkcja przechowywana jako właściwość obiektu).
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'.
więcej o słowie kluczowym this
Dostęp do metod obiektowych, dodawanie metod
Właściwość zostanie wykonana (jako funkcja), gdy zostanie wywołana za pomocą ()
objectName.methodName()
Dostęp do właściwości bez (), zwróci definicję funkcji.
Obiekty zdefiniowane takie jak np. String mają własności (i metody) wbudowane, np.
"Ala".toUpperCase()
Dodawanie metody do istniejącego obiektu:
osoba.pseudonim = function () { return this.imie + "" + this.wiek;};

Atrybuty właściwości

Jednym z atrybutów właściwości obiektu jest wartość.
Pozostałe atrybuty właściwości to: wyliczalność (enumerable), konfigurowalność (configurable) i zapisywalność (writable).
Odczytać można wszystkie atrybuty ale tylko wartość można swobodnie zmienić (o ile jest writable). Pozostałe działania dostępne są (w ECMAScript 5) poprzez metody getter i setter. 🛠 więcej

Tworzenie obiektu

Istnieją różne sposoby tworzenia nowych obiektów:
  1. używając literału obiektu (zdefiniowanie i utwórzenie pojedynczego obiektu)
  2. za pomocą słowa kluczowego new (zdefiniowanie i utwórzenie pojedynczego obiektu)
  3. za pomocą zdefiniowanego konstruktora obiektów i utworzenia obiektów (typu skonstruowanego).
  4. za pomocą funkcji Object.create()
1 - Tworzenie obiektu używając literału

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"
};
2 - Tworzenie obiektu za pomocą słowa kluczowego 'new'
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.
3 🛠 i 4 🛠

Wyświetlanie obiektów JS

Ponieważ wyświetlanie całego obiektu zwraca nam [object Object] to prócz wyświetlania własności w pętli for... in możemy dowolny obiekt JavaScript przekonwertować na tablicę. Robimy to za pomocą metody Object - Object.values(obiekt)
var osoba = {imie: "Piotr", nazwisko: "Zalewski", wiek: 44, kolorOczu: "niebieski"};
var tablica=Object.values(osoba);
alert(tablica);  // zwróci: Piotr,Zalewski,44,niebieski
Innym 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(); 

Obiekty cz. II

Akcesory

Funkcje gettera i setera

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ą.
expression - w ECMAScript 2015 - wyrażenie dla obliczenia nazwy właściwości w celu powiązana z daną 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); 
Metoda Object.defineProperty()
Metoda Object.defineProperty() może być użyta do dodawania seterów i getterów:
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);

Konstruktory

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;};
...
Wbudowane konstruktory JS dla obiektów natywnych
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 Date
Obiekt Math() nie znajduje się na liście, jest obiektem globalnym. Nie można użyć słowa kluczowego new Math.
Nie ma powodu, aby tworzyć złożone obiekty. Wartości pierwotne są znacznie szybsze:
- Użyj literałów obiektowych {} zamiast new Object()
- Użyj literałów łańcuchowych "" zamiast new String().
- Użyj literałów liczbowych 12345 zamiast new Number().
- Użyj literałów logicznych true/false zamiast new Boolean().
- Użyj literałów tablicowych [] zamiast new Array().
- Użyj literałów wzorców /()/ zamiast new RegExp().
- Użyj wyrażeń funkcyjnych () {}zamiast new Function().
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

Prototypy. Object.prototype

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

menu jest po prawej stronie -->