Skip to content

3. Objects (обьекты)

Igor Demin edited this page Oct 31, 2023 · 12 revisions

Объекты

Объект - это набор св-в, а у св-в есть свои значения. Объект это тип значений, а так же тип переменных т.е. можно сказать что эта переменная - объект или её тип это объект.
Метод - это значение свойства выраженное функцией

Порядок св-тв объекта не важен, если изменить порядок или создать объект с такими же свойствами но другим порядком, то с точки зрения JS это будет идентичный объект.

ПРИМЕР 1: Получаем значение св-ва объекта

const myCity = {
  city: 'New york',
  popular: true,
  country: 'USA'
}

console.log(myCity.city) // получим 'New york'

console.log(myCity.popular) // получим true

ПРИМЕР 2: Меняем и добавляем св-ва объекта

const myCity = {
  city: 'New york'
}

myCity.popular = true

console.log(myCity) // {city: 'New york', popular: true}

ВАЖНО: Заметим что переменная объявлена с помощью const, а мы меняем/добавляем значения объекта. Но мы в этом примере не меняем значение переменной т.е. не присваиваем новое значение, мы меняем объект, при этом сама переменная как содержала ссылку на объект так и содержит. Другими словами мы мутируем этот объект не меняя значения переменной.

ПРИМЕР 3: Удаляем св-во

const myCity = {
  city: 'New york',
  popular: true,
  country: 'USA'
}

delete myCity.country 
delete myCity['country'] // или можно использовать запись с квадратными скобками

console.log(myCity) // { city: 'New york', popular: true }

Вложенные св-ва и вложенные объекты

const myCity = {
  city: 'New york',
  info: {
    isPopular: true,
    country: 'USA'
  }
}

console.log(myCity.info.isPopular) // true

delete myCity.info['isPopular']

console.log(myCity) // { city: 'New york', info: { country: 'USA' } }

ВАЖНО: Использовать запись с квадратными скобками следует при удалении выражения(например название переменной), во всех других случаях следует использовать точечную запись.

Переменные в объекте и сокращенный формат

Мы можем легко использовать переменные как значения для св-в объекта, и более того в качестве значений св-в объекта можно использовать выражения. Сначала JS получит результат выражения, а после этого результат присвоится св-ву объекта.

const name = 'igor'
const postQty = 23

const userProfile = {
  name: name,
  postQty: postQty,
  hasSignedAgreement: false
}

ВАЖНО: Обратим внимание что в примере выше название переменной совпадает с названием св-ва объекта name: name и postQty: postQty, в этом случае можно использовать сокращённую запись(сокращенные записи рекомендуется ставить в начала объекта):

const name = 'igor'
const postQty = 23

const userProfile = {
  name,
  postQty,
  hasSignedAgreement: false
}

Глобальный объекты

image

В объекте window очень много св-в, в консоли браузера можно их посмотреть:

> window.innerWidth
<- 224

В nodejs объект global смотрим так:

global

ВАЖНО: т.к. в браузере и в nodejs глобальные объекты разные, то решили сделать Унифицированный глобальный объект globalThis. И как раньше мы получали св-во объекта в браузере с помощью объекта window, теперь сможем получать с помощью globalThis и так же в nodejs

image

Св-ва глобальных объектов

Мы уже знаем что есть такой объект как console и вызывали его ранее и вызывали один из его методов log. И на самом деле этот объект console является св-вом глобального объекта window или global

console.log(10) // получим в браузере и в nodejs 10

window.console.log(10) // в браузере получим 10
global.console.log(10) // в nodejs получим 10

Методы объекта

метод - св-во объекта, значение которого - функция
В данном примере cityGreeting это метод, а city просто св-во т.к. его значение не является фукцией.
myCity.cityGreeting () - а так мы вызываем метод с помощью скобок ()

const myCity = {
  city: 'New York',
  cityGreeting: function () {
    console.log('Greetings!!')
  }
}

myCity.cityGreeting ()
// 'Greetings!!'

Сокращенный формат записи методов

Если убрать ключевое слово function и оставить только () то так пучится сокращённый формат записи

const myCity = {
  city: 'New York',
  cityGreeting() {
    console.log('Greetings!!')
  }
}

myCity.cityGreeting()
// 'Greetings!!'

Вызов метода vs вызов св-ва

myCity.city // так вызываются св-ва
myCity.cityGreeting() // так вызываются методы

JSON

javascript object notation - формат обмена данных между серверами или клиентом и сервером

{
  "userId": 1,
  "id": 1,
  "title": "Test title",
  "status": {
    "complited": false
  }
}

При этом передача данных происходит в виде строки string

{"userId": 1,"id": 1,"title": "Test title","status": {"complited": false}}

ВОПРОС: как конвертировать JSON в объект JS или наоборот?
image

Для этого есть встроенный метод parse, а точнее JSON.parse(). Если передать такой JSON в методе parse, то получим JS объект без кавычек и с такими же данными:

{
  userId: 1,
  id: 1,
  title: 'Test title',
  status: {
    complited: false
  }
}

и если нужно наоборот, то есть метод JSON.stringify()
image ПРИМЕР: Переведем объект JS в JSON и обратно

const post = {
    title: 'my post',
    likesQty: 5
}

JSON.stringify(post) // получим '{"title":"my post","likesQty":5}'

const postStringified = JSON.stringify(post) // создадим новую переменную postStringified с строкой в формате JSON которую мы получили

JSON.parse(postStringified) // получаем {title: 'my post', likesQty: 5}

Мутации объектов

ПРИМЕР 1: копирование значений примитивных типов, на англ copy by value

const a = 10
let b = a // copy by value
b = 30

console.log(a) // 10
console.log(b) // 30

ПРИМЕР 2: мутации объекта на который ссылается переменная:

const person = {
  name: 'Bob',
  age: 21
}

person.age = 22
person.isAdult = true

console.log(person.age) // 22
console.log(person.isAdult) // true

ПРИМЕР 3: мутирование копий, тут мы изменяем св-ва второй переменной, а св-ва объекта изменятся у обоих переменных т.к. они хранят только ссылку на объект сopy by reference.

const person = {
  name: 'Bob',
  age: 25
}

const person2 = person // сopy by reference

person2.age = 26
person2.isAdult = true

console.log(person.age) // 26
console.log(person.isAdult) // true

Как избежать мутаций

ВАРИАНТ 1: Можем создать копию объекта с помощью глобального объекта Object и его метода Object.assign. Далее изменять копию не меняя оригинальный объект (Object с большой буквы т.к. он и тип и класс в JS и он же является прототипом всех объектов в JS):

const person = {
  name: 'Bob',
  age: 25
}

const person2 = Object.assign({}, person)

person2.age = 26

console.log(person2.age) // 26
console.log(person.age) // 25

ПРИМЕЧАНИЕ: Если у объекта есть вложенные объекты, то ссылки на них сохраняются и они могу быть изменены, поэтому частично может быть изменён оригинальный объект. Этот вариант подходит если нет вложенных объектов.

ВАРИАНТ 2: Использовать оператор разделения объекта на св-ва .... У него таже проблема что и в 1 варианте, но зато запись проще и короче.

const person = {
  name: 'Bob',
  age: 25
}

const person2 = { ...person }

person2.name = 'Alice'

console.log(person2.name) // Alice
console.log(person.name) // Bob

ВАРИАНТ 3: Путем двойной конвертации создать новый объект. В этом случае создадим новый объект и все вложенные объекты будут созданы в другом месте в памяти.

const person = {
  name: 'Bob',
  age: 25
}

const person2 = JSON.parse(JSON.stringify(person))

person2.name = 'Alice'

console.log(person2.name)
console.log(person.name)