5. Obiekty literałowe
W tym kontekście terminem „obiekty literałowe” określamy obiekty zdefiniowane dosłownie w kodzie. W języku JavaScript istnieje pojęcie klasy oraz obiektu będącego instancją klasy. Nie jest to zatem ten rodzaj obiektu, o którym obecnie mówimy.

5.1. skrypt [obj-01]
Przedstawiamy tutaj podstawowe właściwości obiektów literałowych. Najważniejszą z nich jest to, że obiektem manipuluje się za pomocą wskaźnika.
'use strict';
// pusty obiekt
const obj1={};
// można dynamicznie tworzyć właściwości obiektu
obj1.prop1="abcd";
console.log('obj1=',obj1);
// inna właściwość
obj1.prop2=[1,2,3];
console.log("obj1=",obj1);
// inna właściwość zapisana w inny sposób
obj1['prop3']=true;
console.log("obj1=",obj1);
// obj1 jest odwołaniem do obiektu (wskaźnikiem), a nie samym obiektem
const obj2=obj1;
// obj2 i obj1 wskazują na ten sam obiekt
obj2.prop1="xyzt";
console.log("obj1=",obj1);
console.log("obj2=",obj2);
// właściwości mogą być zmiennymi
const var1='prop1';
console.log('prop1=',obj1[var1]);
Wykonanie
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe "c:\Temp\19-09-01\javascript\objets\obj-01.js"
obj1=[object Object]
obj1= { prop1: 'abcd', prop2: [ 1, 2, 3 ] }
obj1= { prop1: 'abcd', prop2: [ 1, 2, 3 ], prop3: true }
obj1= { prop1: 'xyzt', prop2: [ 1, 2, 3 ], prop3: true }
obj2= { prop1: 'xyzt', prop2: [ 1, 2, 3 ], prop3: true }
prop1= xyzt
Komentarze
- wiersz 3 kodu: obiekt jest obsługiwany za pomocą wskaźnika. Zatem [obj1] jest wskaźnikiem. Modyfikacja obiektu, na który wskazuje wskaźnik, nie powoduje zmiany samego wskaźnika [obj1]. Dlatego, podobnie jak w przypadku tablic, referencja do obiektu jest deklarowana za pomocą słowa kluczowego [const];
- wiersz 6 kodu: podobnie jak w przypadku tablic, [console.log] potrafi wyświetlać obiekty;
- wiersz 11 kodu: obj1.prop3 można zapisać jako obj1.[‘prop3’]. Ten ostatni zapis jest przydatny, gdy „prop3” jest w rzeczywistości zmienną (wiersze 20–21);
- wiersze 13–18 kodu: pokazują, że instrukcja [obj2=obj1] stanowi kopiowanie przez odwołanie do obiektu, a nie samego obiektu;
5.2. skrypt [obj-02]
Skrypt ten pokazuje, że właściwości obiektu mogą przyjmować wartość obiektu. W ten sposób powstają obiekty wielopoziomowe. Wprowadzono również obiekt globalny [JSON], który umożliwia konwersję między obiektem a ciągiem znaków.
'use strict';
// obiekt wielopoziomowy
const personne = {
prénom: "martin",
âge: 12,
père: {
prénom: "paul",
âge: 45
},
mère: {
prénom: "micheline",
âge: 42
}
}
// dostęp do właściwości
console.log("prénom personne=", personne.prénom);
console.log("prénom mère=", personne.mère.prénom);
personne.mère.âge = 40;
console.log("âge mère=", personne.mère.âge);
// console.log potrafi wyświetlać obiekty
console.log("personne=", personne);
console.log("mère=", personne.mère);
// można również wyświetlić ciąg znaków jSON obiektu
let json = JSON.stringify(personne);
console.log("jSON=", json);
// można ponownie odczytać jSON
let personne2 = JSON.parse(json);
console.log("père=", personne2.père);
Komentarze
- wiersz 24: przekształcenie obiektu JavaScript na ciąg znaków jSON;
- wiersz 27: przekształcenie ciągu znaków jSON w obiekt JavaScript;
Wykonanie
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe "c:\Temp\19-09-01\javascript\objets\obj-02.js"
prénom personne= martin
prénom mère= micheline
âge mère= 40
personne= { 'prénom': 'martin',
'wiek': 12,
'ojciec': { 'imię': 'paul', 'wiek': 45 },
'matka': { 'imię': 'micheline', 'wiek': 40 } }
mère= { 'prénom': 'micheline', 'âge': 40 }
jSON= {"prénom":"martin","âge":12,"père":{"prénom":"paul","âge":45},"mère":{"prénom":"micheline","âge":40}}
père= { 'prénom': 'paul', 'âge': 45 }
Komentarze
- wiersz 10: w ciągu znaków jSON właściwości muszą być ujęte w cudzysłowy, podobnie jak wartości typu ciąg znaków;
5.3. skrypt [obj-03]
Ten skrypt wprowadza pojęcie metod getter i setter właściwości obiektu:
'use strict';
// metody getter i setter obiektu
const personne = {
// getter
get nom() {
console.log("getter nom");
return this._nom;
},
// setter
set nom(unNom) {
console.log("setter nom");
this._nom = unNom;
}
};
// setter
personne.nom = "Hercule";
// metoda pobierająca
console.log(personne.nom);
// sam obiekt
console.log("personne=", personne);
// nie uniemożliwia to bezpośredniego dostępu do właściwości [_nom]
personne._nom = "xyz";
console.log("personne=", personne);
Komentarze
- wiersze 5–7: definicja funkcji [getter], która zazwyczaj zwraca wartość właściwości obiektu, ale w rzeczywistości może zwracać dowolną wartość. Słowo kluczowe [function] zostało zastąpione słowem kluczowym [get];
- wiersz 7: getter zwraca właściwość [_nom]. Widać, że nie trzeba jej deklarować;
- wiersze 10–13: definicja funkcji [setter], która zazwyczaj przypisuje otrzymaną wartość do właściwości obiektu, ale w rzeczywistości może wykonywać dowolną operację. Słowo kluczowe [function] zostaje zastąpione słowem kluczowym [set]. Funkcja [setter] może służyć do sprawdzania poprawności wartości przekazanej jako parametr do funkcji [setter];
- wiersz 16: funkcja [set nom] zostanie wywołana niejawnie;
- wiersz 18: funkcja [get nom] zostanie wywołana niejawnie;
- wiersz 22: pokazuje, że korzystanie z metod getter/setter zależy od decyzji programisty. Jeśli programista zna nazwę właściwości obsługiwanej przez te metody, może uzyskać do niej bezpośredni dostęp;
Wykonanie
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe "c:\Temp\19-09-01\javascript\objets\obj-03.js"
setter nom
getter nom
Hercule
personne= { nom: [Getter/Setter], _nom: 'Hercule' }
personne= { nom: [Getter/Setter], _nom: 'xyz' }
Warto zwrócić uwagę na linie 5–6, gdzie wskaźnik [console.log] wyświetla również właściwości, które są funkcjami.
5.4. skrypt [obj-04]
Ten skrypt pokazuje trzy sposoby zapisywania nazw właściwości obiektu oraz dwa sposoby uzyskiwania do nich dostępu.
'use strict';
// nazwy właściwości obiektu mogą być literałami [nom], otoczone apostrofami ['nom']
// lub cudzysłowami ["nom"]
// literały
const obj1 = {
nom: "martin",
prénom: "jean"
};
console.log("prénom=", obj1.prénom);
// otoczone apostrofami
const obj2 = {
'nazwisko': „martin”,
'imię': „jean”
};
console.log("nom=", obj2.nom);
// w cudzysłowach
const obj3 = {
"nom": "martin",
"prénom": "jean"
};
// dwie możliwe składnie dostępu do właściwości [nom]
console.log("nom=", obj3.nom);
console.log("nom=", obj3['nom']);
Wykonanie
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe "c:\Temp\19-09-01\javascript\objets\obj-04.js"
prénom= jean
nom= martin
nom= martin
nom= martin
5.5. skrypt [obj-05]
Skrypt pokazuje, że właściwości obiektu literałowego mogą być funkcjami. Jesteśmy wtedy bardzo blisko obiektu będącego instancją klasy, w którym występują właściwości i metody.
'use strict';
// obiekt może posiadać właściwości typu [function]
const personne = {
// właściwości
prénom: "martin",
âge: 12,
père: {
prénom: "paul",
âge: 45
},
mère: {
prénom: "micheline",
âge: 42
},
// metoda
toString: function () {
return JSON.stringify(this);
}
}
// zastosowanie
console.log("personne=", personne);
console.log("personne.toString=", personne.toString());
- wiersze 17–19: metoda wewnętrzna obiektu. W tej metodzie uzyskuje się dostęp do właściwości obiektu za pomocą słowa kluczowego [this] (wiersz 18). [this] oznacza sam obiekt, a [this.prénom] – jego właściwość [prénom];
Wykonanie
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe "c:\Temp\19-09-01\javascript\objets\obj-05.js"
personne= { 'prénom': 'martin',
'wiek': 12,
'ojciec': { 'imię': 'paul', 'wiek': 45 },
'matka': { 'imię': 'micheline', 'wiek': 42 },
toString: [Function: toString] }
personne.toString= {"prénom":"martin","âge":12,"père":{"prénom":"paul","âge":45},"mère":{"prénom":"micheline","âge":42}}
5.6. skrypt [obj-06]
Ten skrypt pokazuje, jak uzyskać dostęp do właściwości obiektu, gdy nie znamy z góry ich nazw.
'use strict';
// obiekt może posiadać właściwości typu [function]
let personne = {
// właściwości
prénom: "martin",
âge: 12,
père: {
prénom: "paul",
âge: 45
},
mère: {
prénom: "micheline",
âge: 42
},
// metoda
toString: function () {
return JSON.stringify(this);
}
}
// zastosowanie
console.log(personne);
// właściwości
console.log("-----------------------");
for (const key in personne) {
if (personne.hasOwnProperty(key)) {
const element = personne[key];
console.log(key, "=", element);
}
}
// aby uniknąć ostrzeżenia eslint (1)
console.log("-----------------------");
for (const key in personne) {
if (Object.prototype.hasOwnProperty.call(personne, key)) {
const element = personne[key];
console.log(key, "=", element);
}
}
// aby uniknąć ostrzeżenia eslint (2)
console.log("-----------------------");
for (const key in personne) {
// eslint-disable-next-line no-prototype-builtins
if (personne.hasOwnProperty(key)) {
const element = personne[key];
console.log(key, "=", element);
}
}
Komentarze
- wiersze 26–31: kod umożliwiający uzyskanie listy właściwości obiektu, z wyłączeniem metod. Kod ten jest przedmiotem ostrzeżenia ESLint:

- wiersze 32–39: kod pozwalający uniknąć ostrzeżenia o błędzie ESLint. Wykorzystuje się prototyp klasy [Object];
- wiersze 41–47: albo po prostu wyłączamy ostrzeżenie (wiersz 43);
5.7. skrypt [obj-07]
Skrypt [obj-07] pokazuje możliwość dekonstrukcji obiektu:
'„use strict”;
// dekonstrukcja
// literały
const obj1 = {
nom: "martin",
prénom: "jean"
};
// dekonstrukcja obj1 w zmiennych [n,p]
const { nom: n, prénom: p } = obj1;
console.log("n=", n, "p=", p);
// dekonstrukcja obiektu obj1 do zmiennych [n2,p2]
function f({ nom: n2, prénom: p2 }) {
console.log("f-n2=", n2, "f-p2=", p2);
}
f(obj1);
// dekonstrukcja obiektu obj1 na zmienne [nom,prénom]
function g({ nom: nom, prénom: prénom }) {
console.log("g-nom=", nom, "g-prénom=", prénom);
}
g(obj1);
// dekonstrukcja obiektu obj1 na zmienne [nom,prénom]
// z notacją skróconą równoważną h({nazwisko:nazwisko,imię:imię})
function h({ nom, prénom }) {
console.log("h-nom=", nom, "h-prénom=", prénom);
}
h(obj1);
Komentarze
- wiersz 11: to właśnie nawiasy klamrowe {} umożliwiają dekonstrukcję. Składnia
const { nom: n, prénom: p } = obj1
tworzy dwie zmienne [n] i [p] i jest równoważna następującemu zapisowi:
const n = obj1.nom
const p = obj1.prénom
Deklaracja mogłaby wyglądać następująco:
const { nom => n, prénom => p } = obj1
należy pamiętać, że wartości atrybutów [nom, prénom] trafiają do zmiennych [n, p];
- operacja dekonstrukcji powtarza się w wierszach 15, 21 i 28. Za każdym razem obecność nawiasów klamrowych {} wskazuje, że nastąpi dekonstrukcja obiektu do zmiennych;
- wiersz 28 może budzić pewne wątpliwości. Jest to skrót dla zapisu:
function h({ nom : nom, prénom : prénom })
Wyniki wykonania są następujące:
5.8. skrypt [obj-08]
Skrypt [obj-08] pokazuje, jak uzyskać kopię obiektu:
'use strict'
// klonowanie obiektów
const obj1 = {
nom: "martin",
prénom: "jean"
};
// klon (kopia) obiektu obj1 przy użyciu operatora rozprzestrzeniania
const obj2 = { ...obj1 }
// sprawdzanie
// obj2 wskazuje na kopię obj1
console.log("obj2===obj1 :", obj1 === obj2)
console.log("obj2=", obj2)
- wiersz 10: operacja kopiowania obiektu [obj1]. Operator ... nazywany jest operatorem rozprzestrzeniania;
Wyniki wykonania są następujące:
- wiersz 1: pokazuje, że referencje [obj1] i [obj2] nie wskazują na ten sam obiekt;
- wiersz 2: pokazuje, że obiekt, na który wskazuje [obj2], jest kopią obiektu, na który wskazuje [obj1];
5.9. Conclusion
Skrypty z tej sekcji pokazały, że obiekt literałowy w JavaScript jest zbliżony do obiektu instancji klasy w językach obiektowych. Można w nim definiować właściwości, metody oraz gettery i settery. Jest to obiekt dynamiczny, którego właściwości można definiować w trakcie wykonywania. Zachowuje się on wówczas jak słownik, którego elementy mogą być dowolnego typu, w szczególności typu [fonction].