Skip to content

5. Літеральні об’єкти

Тут ми називаємо «літеральними об’єктами» об’єкти, які визначені безпосередньо в коді. У JavaScript існує поняття класу та об’єкта-інстанції класу. Отже, зараз ми не говоримо про об’єкти цього типу.

Image

5.1. скрипт [obj-01]

Тут ми розглянемо основні властивості літеральних об’єктів. Головна з них полягає в тому, що об’єкт обробляється за допомогою покажчика.


'use strict';
// порожній об’єкт
const obj1={};
// властивості об’єкта можна створювати динамічно
obj1.prop1="abcd";
console.log('obj1=',obj1);
// інша властивість
obj1.prop2=[1,2,3];
console.log("obj1=",obj1);
// інша властивість з іншою нотацією
obj1['prop3']=true;
console.log("obj1=",obj1);
// obj1 — це посилання на об’єкт (покажчик), а не сам об’єкт
const obj2=obj1;
// obj2 та obj1 вказують на один і той самий об’єкт
obj2.prop1="xyzt";
console.log("obj1=",obj1);
console.log("obj2=",obj2);
// властивості можуть бути змінними
const var1='prop1';
console.log('prop1=',obj1[var1]);

Виконання


[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

Коментарі

  • 3-й рядок коду: об’єкт обробляється за допомогою покажчика. Отже, [obj1] є покажчиком. Зміна об’єкта, на який вказує покажчик, не змінює самого покажчика [obj1]. Саме тому, як і у випадку з масивами, посилання на об’єкт оголошується за допомогою ключового слова [const];
  • рядок 6 коду: як і у випадку з масивами, [console.log] вміє відображати об’єкти;
  • рядок 11 коду: obj1.prop3 можна переписати як obj1.[‘prop3’]. Останній варіант запису є корисним, коли «prop3» насправді є змінною (рядки 20–21);
  • рядки 13–18 коду: показують, що інструкція [obj2=obj1] є копією посилання на об’єкт, а не самого об’єкта;

5.2. скрипт [obj-02]

Цей скрипт демонструє, що властивості об’єкта можуть мати значення у вигляді об’єкта. У такому разі ми маємо багаторівневі об’єкти. Також вводиться глобальний об’єкт [JSON], який дозволяє здійснювати перетворення об’єкт ↔ рядок символів.


'use strict';
// багаторівневий об’єкт
const personne = {
  prénom: "martin",
  âge: 12,
  père: {
    prénom: "paul",
    âge: 45
  },
  mère: {
    prénom: "micheline",
    âge: 42
  }
}
// доступ до властивостей
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 вміє відображати об’єкти
console.log("personne=", personne);
console.log("mère=", personne.mère);
// також можна відобразити рядок jSON об’єкта
let json = JSON.stringify(personne);
console.log("jSON=", json);
// можна перечитати jSON
let personne2 = JSON.parse(json);
console.log("père=", personne2.père);

Коментарі

  • рядок 24: перетворення об’єкта JavaScript у рядок jSON;
  • рядок 27: перетворення рядка jSON в об’єкт JavaScript;

Виконання


[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',
'вік': 12,
'батько': { 'ім'я': 'paul', 'вік': 45 },
'«мати»: { «ім'я»: «Мішелін», «вік»: 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 }

Коментарі

  • рядок 10: у рядку jSON властивості обов’язково беруться в лапки, так само як і значення типу «рядок символів»;

5.3. скрипт [obj-03]

Цей скрипт вводить поняття геттера/сеттера властивості об’єкта:


'use strict';
// геттери та сеттери об’єкта
const personne = {
  // геттер
  get nom() {
    console.log("getter nom");
    return this._nom;
  },
  // сеттер
  set nom(unNom) {
    console.log("setter nom");
    this._nom = unNom;
  }
};
// сеттер
personne.nom = "Hercule";
// геттер
console.log(personne.nom);
// сам об’єкт
console.log("personne=", personne);
// це не заважає отримати прямий доступ до властивості [_nom]
personne._nom = "xyz";
console.log("personne=", personne);

Коментарі

  • рядки 5–7: визначення функції [getter], яка зазвичай повертає значення властивості об’єкта, але фактично може повертати що завгодно. Ключове слово [function] замінено на ключове слово [get];
  • рядок 7: геттер повертає властивість [_nom]. Бачимо, що її не потрібно оголошувати;
  • рядки 10–13: визначення функції [setter], яка зазвичай присвоює отримане значення властивості об’єкта, але насправді може робити що завгодно. Ключове слово [function] замінено на ключове слово [set]. [setter] можна використовувати для перевірки правильності значення, переданого як аргумент у [setter];
  • рядок 16: функція [set nom] буде викликана неявно;
  • рядок 18: функція [get nom] буде викликана неявно;
  • рядок 22: показує, що використання геттерів/сеттерів залежить від бажання розробника. Якщо розробник знає ім’я властивості, яку вони обробляють, він може отримати до неї прямий доступ;

Виконання


[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' }

Зверніть увагу на рядки 5–6: [console.log] також відображає властивості, які є функціями.

5.4. скрипт [obj-04]

Цей скрипт демонструє три способи запису імен властивостей об’єкта та два способи доступу до них.


'use strict';
// імена властивостей об’єкта  можуть бути літералами [nom], оточені апострофами ['nom']
// або лапками ["nom"]

// літерали
const obj1 = {
  nom: "martin",
  prénom: "jean"
};
console.log("prénom=", obj1.prénom);

// в апострофах
const obj2 = {
  'ім'я': "martin",
  'ім'я': "jean"
};
console.log("nom=", obj2.nom);

// в лапках
const obj3 = {
  "nom": "martin",
  "prénom": "jean"
};

// дві можливі синтаксичні конструкції для доступу до властивості [nom]
console.log("nom=", obj3.nom);
console.log("nom=", obj3['nom']);

Виконання


[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. скрипт [obj-05]

Скрипт демонструє, що властивості об’єкта-літералу можуть бути функціями. У цьому випадку ми дуже наближаємося до об’єкта-інстанції класу, який має властивості та методи.


'use strict';

// об’єкт може мати властивості типу [function]
const personne = {
  // властивості
  prénom: "martin",
  âge: 12,
  père: {
    prénom: "paul",
    âge: 45
  },
  mère: {
    prénom: "micheline",
    âge: 42
  },
  // метод
  toString: function () {
    return JSON.stringify(this);
  }
}

// використання
console.log("personne=", personne);
console.log("personne.toString=", personne.toString());
  • рядки 17–19: внутрішній метод об’єкта. У ньому доступ до властивостей об’єкта здійснюється за допомогою ключового слова [this] (рядок 18). [this] позначає сам об’єкт, [this.prénom] — його властивість [prénom];

Виконання


[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',
'вік': 12,
'батько': { 'ім'я': 'paul', 'вік': 45 },
'мати': { 'ім'я': 'Мішелін', 'вік': 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. скрипт [obj-06]

Цей скрипт демонструє, як отримати доступ до властивостей об’єкта, якщо заздалегідь невідомі їхні імена.


'use strict';

// об’єкт може мати властивості типу [function]
let personne = {
  // властивості
  prénom: "martin",
  âge: 12,
  père: {
    prénom: "paul",
    âge: 45
  },
  mère: {
    prénom: "micheline",
    âge: 42
  },
  // метод
  toString: function () {
    return JSON.stringify(this);
  }
}

// використання
console.log(personne);
// властивості
console.log("-----------------------");
for (const key in personne) {
  if (personne.hasOwnProperty(key)) {
    const element = personne[key];
    console.log(key, "=", element);
  }
}
// для уникнення попередження eslint (1)
console.log("-----------------------");
for (const key in personne) {
  if (Object.prototype.hasOwnProperty.call(personne, key)) {
    const element = personne[key];
    console.log(key, "=", element);
  }
}
// для уникнення попередження 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);
  }
}

Коментарі

  • рядки 26–31: код, що дозволяє отримати список властивостей об’єкта без методів. Цей код супроводжується попередженням від ESLint:

Image

  • рядки 32–39: код, що дозволяє уникнути попередження ESLint. Для цього використовується прототип класу [Object];
  • рядки 41–47: або просто вимикаємо попередження (рядок 43);

5.7. скрипт [obj-07]

Скрипт [obj-07] демонструє можливість розбиття об’єкта на складові частини:


'use strict';
// деструктурація

// літерали
const obj1 = {
  nom: "martin",
  prénom: "jean"
};

// деструктурація obj1 у змінні [n,p]
const { nom: n, prénom: p } = obj1;
console.log("n=", n, "p=", p);

// деструктурація obj1 у змінні [n2,p2]
function f({ nom: n2, prénom: p2 }) {
  console.log("f-n2=", n2, "f-p2=", p2);
}
f(obj1);

// розпакування obj1 у змінні [nom,prénom]
function g({ nom: nom, prénom: prénom }) {
  console.log("g-nom=", nom, "g-prénom=", prénom);
}
g(obj1);

// розпакування obj1 у змінні [nom,prénom]
// зі скороченим записом, еквівалентним h({прізвище:прізвище,ім'я:ім'я})
function h({ nom, prénom }) {
  console.log("h-nom=", nom, "h-prénom=", prénom);
}
h(obj1);

Коментарі

  • рядок 11: саме фігурні дужки {} дозволяють розбивати структуру. Синтаксис

const { nom: n, prénom: p } = obj1

створює дві змінні [n] та [p] і є еквівалентним:


const n = obj1.nom
const p = obj1.prénom

Оголошення може виглядати наступним чином:


const { nom => n, prénom => p } = obj1

щоб нагадати, що значення атрибутів [nom, prénom] передаються у змінні [n, p];

  • операція деструктуризації повторюється в рядках 15, 21 та 28. Щоразу наявність фігурних дужок {} вказує на те, що відбудеться деструктуризація об’єкта у змінні;
  • рядок 28 може здатися незрозумілим. Це скорочений запис для:

function h({ nom : nom, prénom : prénom })

Результати виконання такі:

1
2
3
4
n= martin p= jean
f-n2= martin f-p2= jean
g-nom= martin g-prénom= jean
h-nom= martin h-prénom= jean

5.8. скрипт [obj-08]

Скрипт [obj-08] демонструє, як отримати копію об’єкта:


'use strict'

// клонування об’єктів
const obj1 = {
  nom: "martin",
  prénom: "jean"
};

// клон (копія) об’єкта obj1 за допомогою оператора розгортання
const obj2 = { ...obj1 }

// перевірки
// obj2 вказує на копію obj1
console.log("obj2===obj1 :", obj1 === obj2)
console.log("obj2=", obj2)
  • рядок 10: операція копіювання об’єкта [obj1]. Оператор ... називається оператором розширення;

Результати виконання такі:

obj2===obj1 : false
obj2= { nom: 'martin', 'prénom': 'jean' }
  • рядок 1: показує, що посилання [obj1] та [obj2] не вказують на один і той самий об’єкт;
  • рядок 2: показує, що об’єкт, на який вказує [obj2], є копією об’єкта, на який вказує [obj1];

5.9. Conclusion

Скрипти цього розділу продемонстрували, що літеральний об’єкт у JavaScript близький до екземпляра класу в об’єктно-орієнтованих мовах програмування. У ньому можна визначати властивості, методи та геттери/сеттери. Це динамічний об’єкт, властивості якого можна визначати під час виконання. У такому разі він поводиться як словник, елементи якого можуть бути будь-якого типу, зокрема типу [fonction].