Inicjalizator obiektu

To tłumaczenie jest niekompletne. Pomóż przetłumaczyć ten artykuł z języka angielskiego.

Obiekty można tworzyć używając new Object(), Object.create(), bądź wykorzystując notację literałową (notację inicializacyjną). Inicjalizator obiektu to lista zera lub więcej par - nazw właściwości oraz ich wartości - otoczonych nawiasami klamrowymi ({}).

Składnia

var o = {};
var o = { a: "foo", b: 42, c: {} };

var a = "foo", b = 42, c = {};
var o = { a: a, b: b, c: c };

var o = 
{ 
  wlasciwos: function ([parametry]) {}, 
  get wlasciwos() {}, 
  set wlasciwos(wartosc) {}, 
};

Nowe notacje w ECMAScript 2015

Pamiętaj aby zapoznać się z tabelą kompatybilności. Środowiska nie obsługujące tych notacji będą wyrzucać błędy składni.

// Skrótowe nazwy właściwości (ES6)
var a = "foo", b = 42, c = {};
var o = { a, b, c };

// Skrótowe nazwy metod (ES6)
var o = {
  wlasciwosc([parametry]) {},
  get wlasciwosc() {},
  set wlasciwosc(wartosc) {},
  * generator() {}
};

// Obliczone nazwy właściwości (ES6)
var nazwa = "foo";
var o = {
  [nazwa]: "dzien",
  ["b" + "ar"]: "dobry",
};

Opis

Inicjalizator obiektu to wyrażenie opisujące inicjalizację obiektu Object. Obiekty składają się z właściwości używanych do opisywania obiektu. Wartości tych właściwości mogą zawierać primitive typy danych albo inne obiekty.

Tworzenie obiektów

Pusty obiekt możemy stworzyć w taki sposób:

var obiekt = {};

Jednak prawdziwą przewagą notacji literałowej jest możliwość tworzenia w szybki sposób obiektów ze zdefiniowanymi od razu właściwościami. Wystarczy wypisać listę kluczy: wartości odzdzielonych dwukropkiem. Poniższy przykład tworzy obiekt osoba z trzema właściwościami: "imie", "wiek" i "wyglad". Ich wartościami jest string "Adam", numer 42 oraz inny obiekt.

var osoba = 
{
  imie: "Adam",
  wiek: 42,
  wyglad: { wzrost: 179 },
}

Dostęp do właściwości

Kiedy już stworzyłeś obiekt, możesz chcieć zobaczyć lub zmienić jego właściwości. Można zrobić to używając zapisu z kropką lub nawiasami. Zajrzyj do operatorów pamięci po więcej informacji.

object.imie; // "Adam"
object["wiek"]; // 42

object.imie = "Ewa";

Definiowanie właściwości

Nauczyliśmy się już jak zapisywać właściwości używając notacji literałowej. Czasami jednak mamy w kodzie zmienne, które chcielibyśmy dodać do naszego obiektu. Możemy to zrobić w taki sposób:

var a = "foo", 
    b = 42,
    c = {};

var o = 
{ 
  a: a,
  b: b,
  c: c
};

Ale ECMAScript 2015 oddaje nam do dyspozycji krótszy zapis, pozwalający uzyskać ten sam efekt:

var a = "foo", 
    b = 42, 
    c = {};

// Skrótowe nazwy właściwości (ES6)
var o = { a, b, c };

Duplikowanie nazw właściwości

W momencie, gdy użyjemy już istniejącej nazwy właściwości jej wartość nadpisze tę poprzednią.

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

W ECMAScript 5 strict mode, duplikowanie nazw właściwości było postrzegane jako SyntaxError. Zmieniono to jednak po wprowadzeniu obliczanych nazw właściwości. Duplikacja stała się wówczas możliwa podczas wykonywania kodu, dlatego też w ECMAScript 2015 usunięto tę rystrykcję.

function czyES6UmozliwiaDuplikowanieWlasciwosci()
{
  "use strict";
  try 
  {
    ({ prop: 1, prop: 2 });

    // Nie wyrzucono błędu, duplikacja dozwolona w strict mode.
    return true;
  } 
  catch (e) 
  {
    // Wyrzucono błąd, duplikacja w strict mode zabroniona.
    return false;
  }
}

Definicje metod

Właściwość obiektu może również odnosić się do funkcji albo metody getter lub setter.

var o = {
  wlasciwos: function ([parametry]) {},
  get wlasciwos() {},
  set wlasciwos(wartosc) {},
};

w ECMAScript 2015, mamy dostęp do skróconego zapisu, takiego w którym słowo kluczowe "function" nie jest nam już potrzebne.

// Shorthand method names (ES6)
var o = {
  property([parameters]) {},
  get property() {},
  set property(value) {},
  * generator() {}
};

W ECMAScript 2015 możemy również w prostszy sposób zapisać właściwość będącą funkcją generatora:

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

W ECMAScript 5 musielibyśmy zapisać to tak (aczkolwiek pamiętaj że w ES5 nie ma generatorów):

var o = {
  generator: function *() {
    ...........
  }
};

Po więcej informacji zajrzyj do definicji metod.

Obliczone nazwy właściwości

Od ECMAScript 2015, składnia inicjalizatora obiektu wspiera także obliczone nazwy właściwości. Umożliwia to umieszczenie wyrażenia w nawiasach [], które potem zostanie przeliczone na nazwę właściwości. Działa to na tej samej zasadzie co zapis klamrowy w operatorach pamięci, z którymi zapewne miałeś już styczność. Teraz możemy użwać tej samej składni w notacji literałowej:

// Obliczone nazwy właściwości (ES6)
var i = 0;
var 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

var param = 'typ';
var info = {
  [param]: 'strona',
  ["pod" + param.charAt(0).toUpperCase() + param.slice(1)]: 'forum'
};

console.log(info); // { typ: 'strona', 'podTyp': 'forum' }

Zmiana prototypu

Definicja właściwości w formie __proto__: wartosc albo "__proto__": wartosc nie stworzy właściwości z nazwą __proto__. Zamiast tego, jeżeli podana wartość jest obiektem lub typem null, zamieni ona [[Prototype]] tworzonego obiektu na podaną wartość. (Jeżeli wartość nie jest ani obiektem ani typem null prototyp nie zostanie zmieniony.)

var obj1 = {};
console.log(Object.getPrototypeOf(obj1) === Object.prototype); // true

var obj2 = { __proto__: null };
console.log(Object.getPrototypeOf(obj2) === null); // true

var protoObj = {};
var obj3 = { "__proto__": protoObj };
console.log(Object.getPrototypeOf(obj3) === protoObj); // true

var obj4 = { __proto__: "not an object or null" };
console.log(Object.getPrototypeOf(obj4) === Object.prototype); // true
console.log(!obj4.hasOwnProperty("__proto__")); // true

Podczas notacji literałowej możemy zmienić prototyp tylko raz, kolejne próby będą skutkować błędami składni.

Jeżeli użyjemy w defninicji nazwy __proto__ bez używania składni z dwukropkiem, nazwa ta będzie się zachowywać jak kazda inna.

var __proto__ = "wartosc";

var obj1 = { __proto__ };
console.log(Object.getPrototypeOf(obj1) === Object.prototype); // true
console.log(obj1.hasOwnProperty("__proto__")); // true
console.log(obj1.__proto__ === "wartosc"); // true

var obj2 = { __proto__() { return "witaj"; } };
console.log(obj2.__proto__() === "witaj"); // true

var obj3 = { ["__prot" + "o__"]: 17 };
console.log(obj3.__proto__ === 17); // true

Notacja literałowa vs JSON

Notacja literałowa to nie to samo co JavaScript Object Notation (JSON). Pomimo, że wyglądają podobnie, są miedzy nimi poważne różnice:

  • JSON dopuszcza tylko składnie "wlasnosc": wartosc.  Nazwa własności musi być w cudzysłowie, a defnicja nie może być skrócona.
  • W JSON wartościami moga być tylko string'i, liczby, tablice, true, false, null, lub inny obiekt JSON.
  • Funkcja nie może być przypisana do wartości w JSON.
  • Obiekty jak Date zostaną zamienione na string po użyciu JSON.parse().
  • JSON.parse() odrzuni obliczone nazwy zmiennych oraz wyrzuci błąd.

Specyfikacje

Specification Status Comment
ECMAScript 1st Edition (ECMA-262) Standard Początkowa definicja.
ECMAScript 5.1 (ECMA-262)
The definition of 'Object Initializer' in that specification.
Standard Dodano metody getter oraz setter.
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'Object Initializer' in that specification.
Standard Skrócone nazwy właściwości/metod oraz obliczone nazwy właściwości.
ECMAScript 2017 Draft (ECMA-262)
The definition of 'Object Initializer' in that specification.
Draft  

Kompatybilność z przeglądarkami

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support 1.0 1.0 (1.7 or earlier) 1 1 1
Computed property names (Yes) 34 (34) No support No support 7.1
Shorthand property names (Yes) 33 (33) No support No support No support
Shorthand method names 42.0 34 (34) No support No support No support
Feature Android Android Webview Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile Chrome for Android
Basic support (Yes) (Yes) 1.0 (1.0) 1 1 1 1.0
Computed property names No support (Yes) 34.0 (34) No support No support No support No support
Shorthand property names No support (Yes) 33.0 (33) No support No support No support No support
Shorthand method names No support 42.0 34.0 (34) No support No support No support 42.0

Zobacz również

Autorzy i etykiety dokumentu

 Autorzy tej strony: JacobDesight, bouzlibop
 Ostatnia aktualizacja: JacobDesight,