Объекты

Объекты представляют собой дискретный тип данных, точно так же, как каждый примитив является типом данных, с одним важным отличием: в отличие от примитивов, объекты изменяемы . Объект может содержать данные, связанные с идентификаторами, например, переменная, но он сохраняет тип данных object независимо от того, какие данные он содержит.

За исключением примитивов, все значения JavaScript являются объектами, однако, поскольку даже примитивные литералы демонстрируют объектно-подобное поведение из-за прототипного наследования , часто говорят, что JavaScript фактически состоит из объектов.

Литерал объекта — это пара фигурных скобок, заключающая в себя ноль или более пар ключ-значение, называемых «свойствами», которые могут содержать любое значение JavaScript.

{
    "myProperty" : true
}

Ключами свойств могут быть любые символы или строки . Как и при присвоении идентификатора переменной, строки, используемые в качестве ключей свойств, должны быть предсказуемыми и описательными:

let carAttributes = {
    "color" : "red"
};

carAttributes
> Object { color: "red" }

Для ключей свойств требуется строковый литерал с одинарными ( ' ) или двойными кавычками ( " ), а не шаблонный литерал :

let carAttributes = {
    `keyString` : false
};
> Uncaught SyntaxError: expected property name, got template literal

Значения свойств могут иметь любой тип данных. Свойства объекта сами могут содержать объекты со своими свойствами:

let myObject = {
    'key' : {
        'subkey' : true,
        'othersubkey' : false
    }
};

myObject;
> Object { key: Object { subkey: true, othersubkey: false } }

Если значение свойства является функцией, это свойство называется «методом».

const myObject = {
    "myProperty" : true,
    myMethod() {
        console.log( "This is a method." );
    }
}

myObject.myProperty;
> true

myObject.myMethod();
> "This is a method."

Вы также можете создать объект, используя new ключевое слово:

let myObject = new Object();

В предыдущих примерах вновь созданные литералы объектов были присвоены переменным. Это не обязательно, поскольку, как и любой другой тип данных, вы можете использовать объект без идентификатора везде, где ожидается объект. Однако литерал объекта требует круглых скобок в любом контексте, где его можно спутать с оператором блока, учитывая, что они имеют общий синтаксис фигурных скобок ( {} ). Инициализация переменной никогда не требует этого.

{ "value" : 2 }
> Uncaught SyntaxError: unexpected token: ':'

({ "value" : 2 })
> Object { value: 2 }

let valObj = { "value" : 2 };

valObj;
> Object { value: 2 }

В отличие от примитивов, нет существенной разницы в результатах создания объекта с помощью new Object() и создания литерала объекта, поскольку результатом в любом случае будет объект со свойствами, унаследованными от прототипа Object . Однако между этими двумя синтаксисами есть одно практическое различие.

new ключевое слово должно определять пустой объект, который позже заполняется данными:

let myObject = new Object();

myObject.booleanValue = true;
myObject.stringValue = "My string.";

Литерал объекта может быть заполнен данными при его создании:

let myObject = {
    'booleanValue' : true,
    'stringValue' : "My string."
};

Хотя он имеет мало практического применения, new Object() может использоваться для преобразования примитивных значений данных в объекты соответствующего типа, например те, которые возвращаются с помощью ключевого слова new вместе с их функцией -конструктором . Например, следующее функционально эквивалентно new Number( 10 ) :

let myObject = new Object( 10 );

myObject;
> Number { 10 }

Значения null и undefined приводят к созданию пустого объекта, функционально идентичного вызову new Object() без предоставления аргумента.

Передача литерала объекта в new Object() в качестве аргумента передает литерал объекта без его изменения:

let myObject = new Object( { myValue : 10 } );

myObject;
> Object { myValue: 10 }

Как и в случае с использованием конструкторов для примитивных значений, использование конструкторов для объектов редко имеет какие-либо преимущества по сравнению с использованием литеральной записи объекта. Даже при создании пустых объектов, которые будут заполнены значениями позже, разработчики склонны отдавать предпочтение буквальным обозначениям объектов ради простоты.

Проверьте свое понимание

Какие обозначения можно использовать для задания свойств объекта?

Точечное обозначение
Обозначение в скобках
Обозначение периода
Обозначение строки

Что из следующего является правильным синтаксисом для получения значения myProp ?

myObj["myProp"];
myObj{"myProp"};
myObj("myProp");