--- title: Ініціалізатор об’єкта slug: Web/JavaScript/Reference/Operators/Object_initializer tags: - ECMAScript 2015 - JSON - JavaScript - Об'єкт - властивості - літерал - методи - мутація - обчислені translation_of: Web/JavaScript/Reference/Operators/Object_initializer original_slug: Web/JavaScript/Reference/Operators/Ініціалізація_об’єктів ---
{{JsSidebar("Operators")}}

Об'єкти можна ініціалізувати через new Object()Object.create(), або за допомогою літеральної нотації (нотації ініціалізатора). Ініціалізатор об'єкта - це список з нуля або більше розділених комою пар імен властивостей та асоційованих з ними значень об'єкта, записаних у фігурних дужках ({}).

{{EmbedInteractiveExample("pages/js/expressions-objectinitializer.html", "taller")}}

Синтаксис

let o = {}
let o = {a: 'няв', b: 42, c: {}}

let a = 'няв', b = 42, c = {}
let o = {a: a, b: b, c: c}

let o = {
  property: function ([parameters]) {},
  get property() {},
  set property(value) {}
};

Нові позначення у ECMAScript 2015

Будь ласка, перевірте підтримку цих позначень у таблиці сумісностей. У тих середовищах, де вони не підтримуються, вони призведуть до синтаксичних помилок.

// Скорочений запис імен властивостей (ES2015)
let a = 'привіт', b = 42, c = {};
let o = {a, b, c}

// Скорочений запис імен методів (ES2015)
let o = {
  property([parameters]) {}
}

// Обчислювані імена властивостей (ES2015)
let prop = 'foo'
let o = {
  [prop]: 'як',
  ['b' + 'ar']: 'справи'
}

Опис

Ініціалізатор об'єкта - це вираз, який описує ініціалізацію {{jsxref("Object","об'єкта")}}. Об'єкт складається з властивостей, які описують цей об'єкт. Значення властивостей об'єкта можуть містити або {{Glossary("primitive","прості")}} типи даних, або інші об'єкти.

Літеральна нотація об'єкта та JSON

Літеральна нотація об'єкта - це не те саме, що запис об'єктів JavaScript (JavaScript Object Notation, JSON). Хоча вони схожі, між ними є кілька відмінностей:

Приклади

Створення об'єктів

Порожній об'єкт без властивостей може бути створений так:

let object = {}

Однак, перевагою літералу або ініціалізатора об'єкта є те, що ви можете швидко створити об'єкт з властивостями всередині фігурних дужок. Ви просто позначаєте список пар key: value, розділених комами.

Наступний код створює об'єкт з трьома властивостями, його ключами є "foo", "age" та "baz". Значеннями цих ключів є рядок "bar", число 42, а третя властивість має інший об'єкт в якості свого значення.

let object = {
  foo: 'bar',
  age: 42,
  baz: {myProp: 12}
}

Доступ до властивостей

Коли ви створили об'єкт, ви можете захотіти прочитати чи змінити його. До властивостей об'єкта можна звертатись, використовуючи крапкову нотацію або дужкову нотацію. Читайте Доступ до властивостей, щоб дізнатись більше.

object.foo // "bar"
object['age'] // 42

object.foo = 'baz'

Визначення властивостей

Ми вже дізнались, як позначати властивості за допомогою синтаксису ініціалізатора. Часто у коді є змінні, які ви б хотіли використати в об'єкті. Ви побачите код на зразок такого:

let a = 'foo',
    b = 42,
    c = {};

let o = {
  a: a,
  b: b,
  c: c
}

У ECMAScript 2015 є коротше позначення, яке робить те саме:

let a = 'foo',
    b = 42,
    c = {};

// Скорочений запис імен властивостей (ES2015)
let o = {a, b, c}

// Іншими словами,
console.log((o.a === {a}.a)) // true

Дублювання імен властивостей

Якщо використовуються однакові імена властивостей, друга властивість перепише першу.

var a = {x: 1, x: 2};
console.log(a); // {x: 2}

У строгому режимі ECMAScript 5 дублювання імен властивостей вважалося помилкою {{jsxref("SyntaxError")}}. З появою обчислюваних імен властивостей, що робило дублювання можливим під час виконання, це обмеження було прибране з ECMAScript 2015.

function haveES2015DuplicatePropertySemantics() {
  'use strict';
  try {
    ({prop: 1, prop: 2});

    // Помилка не викидається, дублікати дозволені у строгому режимі
    return true;
  } catch(e) {
    // Помилка викидається, дублікати заборонені у строгому режимі
    return false;
  }
}

Визначення методів

Властивість об'єкта може також посилатись на функцію або гетер чи сетер.

let o = {
  property: function ([parameters]) {},
  get property() {},
  set property(value) {}
}

У ECMAScript 2015 доступне скорочене позначення, тому ключове слово "function" більше не є обов'язковим.

// Скорочений запис імен методів (ES2015)
let o = {
  property([parameters]) {},
}

У ECMAScript 2015 є можливість стисло визначати властивості, значеннями яких є функції-генератори:

let o = {
  *generator() {
    ...........
  }
};

Що є еквівалентним цьому позначенню в стилі ES5 (але зауважте, що у ECMAScript 5 немає генераторів):

let o = {
  generator: function* () {
    ...........
  }
}

Більше інформації та прикладів щодо методів дивіться у статті визначення методів.

Обчислювані імена властивостей

Починаючи з ECMAScript 2015, синтаксис об'єктного ініціалізатора також підтримує обчислювані імена властивостей. Це дозволяє розташувати вираз у квадратних дужках [], і він буде обчислений як ім'я властивості. Цей синтаксис є аналогічним дужковій нотації у доступі до властивостей, який ви вже могли використовувати, щоб читати та встановлювати властивості. Тепер ви можете використовувати такий самий синтаксис і для об'єктних літералів:

// Обчислювані імена властивостей (ES2015)
let i = 0
let a = {
  ['foo' + ++i]: i,
  ['foo' + ++i]: i,
  ['foo' + ++i]: i
}

console.log(a.foo1) // 1
console.log(a.foo2) // 2
console.log(a.foo3) // 3

let param = 'size'
let config = {
  [param]: 12,
  ['mobile' + param.charAt(0).toUpperCase() + param.slice(1)]: 4
}

console.log(config) // {size: 12, mobileSize: 4}

Розкладені властивості

Пропозиція Rest/Spread Properties for ECMAScript (стадія 4) додає розкладені властивості до об'єктних літералів. Ця функціональність копіює особисті перелічувані властивості з наданого об'єкта у новий об'єкт.

Дрібне клонування (не включає prototype) чи злиття об'єктів тепер можливе з використанням синтаксису, коротшого, ніж {{jsxref("Object.assign()")}}.

let obj1 = { foo: 'bar', x: 42 }
let obj2 = { foo: 'baz', y: 13 }

let clonedObj = { ...obj1 }
// Object { foo: "bar", x: 42 }

let mergedObj = { ...obj1, ...obj2 }
// Object { foo: "baz", x: 42, y: 13 }

Зауважте, що {{jsxref("Object.assign()")}} запускає сетери, а оператор розкладу ні!

Мутація прототипу

Визначення властивості виду __proto__: value чи "__proto__": value не створює властивість з іменем __proto__. Замість цього, якщо надане значення є об'єктом чи null, воно змінює [[Prototype]] створеного об'єкта на це значення. (Якщо значення не є об'єктом чи null, об'єкт не змінюється.)

let obj1 = {};
assert(Object.getPrototypeOf(obj1) === Object.prototype);

let obj2 = {__proto__: null};
assert(Object.getPrototypeOf(obj2) === null);

let protoObj = {};
let obj3 = {'__proto__': protoObj};
assert(Object.getPrototypeOf(obj3) === protoObj);

let obj4 = {__proto__: 'не об\'єкт чи null'};
assert(Object.getPrototypeOf(obj4) === Object.prototype);
assert(!obj4.hasOwnProperty('__proto__'));

У об'єктному літералі дозволена лише одна мутація: декілька мутацій прототипу є синтаксичною помилкою.

Визначення властивостей, які не використовують нотацію з двокрапкою, не є мутаціями прототипу: вони є визначеннями властивостей, які поводяться ідентично до схожих визначень, що використовують будь-яке інше ім'я.

let __proto__ = 'змінна';

let obj1 = {__proto__};
assert(Object.getPrototypeOf(obj1) === Object.prototype);
assert(obj1.hasOwnProperty('__proto__'));
assert(obj1.__proto__ === 'змінна');

let obj2 = {__proto__() { return 'привіт'; }};
assert(obj2.__proto__() === 'привіт');

let obj3 = {['__prot' + 'o__']: 17};
assert(obj3.__proto__ === 17);

Специфікації

Специфікація
{{SpecName('ESDraft', '#sec-object-initializer', 'Object Initializer')}}

Сумісність з веб-переглядачами

{{Compat("javascript.operators.object_initializer")}}

Див. також