HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-02-26
1 <h2>Ошибки видео</h2>
1 <h2>Ошибки видео</h2>
2 <p>На самом деле боксинг срабатывает, даже если мы обращаемся к примитивному типу напрямую</p>
2 <p>На самом деле боксинг срабатывает, даже если мы обращаемся к примитивному типу напрямую</p>
3 <p>Но важно понимать, что у строки нет свойств, прозрачно для нас происходит оборачивание в объект и работает это примерно так: new String('hello').</p>
3 <p>Но важно понимать, что у строки нет свойств, прозрачно для нас происходит оборачивание в объект и работает это примерно так: new String('hello').</p>
4 <h2>Изменение объекта</h2>
4 <h2>Изменение объекта</h2>
5 <p>Обычно, изменение объекта происходит так:</p>
5 <p>Обычно, изменение объекта происходит так:</p>
6 <p>Но что делать, если свойство заранее неизвестно? Тогда можно воспользоваться таким способом:</p>
6 <p>Но что делать, если свойство заранее неизвестно? Тогда можно воспользоваться таким способом:</p>
7 <p>Вычислимые свойства встречаются достаточно часто на этапе создания объекта, по этой причине появился специальный синтаксис, позволяющий задавать подобные свойства в литерале. Дополнительный бонус в том, что при таком подходе в коде пропадают лишние изменения (мутации) и код становится более функциональным:</p>
7 <p>Вычислимые свойства встречаются достаточно часто на этапе создания объекта, по этой причине появился специальный синтаксис, позволяющий задавать подобные свойства в литерале. Дополнительный бонус в том, что при таком подходе в коде пропадают лишние изменения (мутации) и код становится более функциональным:</p>
8 <p>Единственное отличие от стандартного синтаксиса в том, что ключ - это переменная (а не имя), взятая в квадратные скобки.</p>
8 <p>Единственное отличие от стандартного синтаксиса в том, что ключ - это переменная (а не имя), взятая в квадратные скобки.</p>
9 <p>Еще одна интересная возможность объектов в JS - сокращенный синтаксис создания объектов при использовании переменных или констант. Обычное создание выглядит так:</p>
9 <p>Еще одна интересная возможность объектов в JS - сокращенный синтаксис создания объектов при использовании переменных или констант. Обычное создание выглядит так:</p>
10 <p>В примере выше, имя свойства совпадает с именем переменной, в которой хранится нужное значение. JS позволяет написать этот код лаконичнее. Можно просто опустить часть name:. И получится:</p>
10 <p>В примере выше, имя свойства совпадает с именем переменной, в которой хранится нужное значение. JS позволяет написать этот код лаконичнее. Можно просто опустить часть name:. И получится:</p>
11 <p>То же самое работает и для нескольких переменных:</p>
11 <p>То же самое работает и для нескольких переменных:</p>
12 <p>Можно даже мешать разные стили в рамках одного объекта:</p>
12 <p>Можно даже мешать разные стили в рамках одного объекта:</p>
13 <p>--</p>
13 <p>--</p>
14 <p>Теперь, когда мы уже хорошо понимаем в чём соль объектно-ориентированного программирования, мы можем познакомиться с настоящими нативными объектами, которые реализованы прямо в JS.</p>
14 <p>Теперь, когда мы уже хорошо понимаем в чём соль объектно-ориентированного программирования, мы можем познакомиться с настоящими нативными объектами, которые реализованы прямо в JS.</p>
15 <p>Разберём простой пример:</p>
15 <p>Разберём простой пример:</p>
16 <p>Записываем в константу строчку и после этого используем известный уже для нас синтаксис доступа к свойствам, только не через модуль, а через объект. Это очень похожий механизм, когда мы вызывали методы или передавали сообщение. Например, с помощью length, мы можем посмотреть длину строчки:</p>
16 <p>Записываем в константу строчку и после этого используем известный уже для нас синтаксис доступа к свойствам, только не через модуль, а через объект. Это очень похожий механизм, когда мы вызывали методы или передавали сообщение. Например, с помощью length, мы можем посмотреть длину строчки:</p>
17 <p>Метод toUpperCase возвращает нам новую строчку (он не мутирует текущую), которая переводит строчку в верхний регистр:</p>
17 <p>Метод toUpperCase возвращает нам новую строчку (он не мутирует текущую), которая переводит строчку в верхний регистр:</p>
18 <p>Если мы не будем делать вызов после toUpperCase, а просто сделаем обращение к свойству и распечатаем, то что лежит внутри, мы увидим, что там лежит function:</p>
18 <p>Если мы не будем делать вызов после toUpperCase, а просто сделаем обращение к свойству и распечатаем, то что лежит внутри, мы увидим, что там лежит function:</p>
19 <p>В большинстве языков принято разделять понятия свойства и методы и говорить об этом явно. В JavaScript нет методов, есть только свойства, просто в некоторых свойствах могут лежать функции, что довольно просто, потому что с функциями мы уже довольно хорошо знакомы: их можно куда угодно записывать, можно передавать как аргументы, получать как значения.</p>
19 <p>В большинстве языков принято разделять понятия свойства и методы и говорить об этом явно. В JavaScript нет методов, есть только свойства, просто в некоторых свойствах могут лежать функции, что довольно просто, потому что с функциями мы уже довольно хорошо знакомы: их можно куда угодно записывать, можно передавать как аргументы, получать как значения.</p>
20 <p>С объектом примерно также. Есть некоторый объект внутри переменной или константы, точка - вызов какого-то свойства, которое может быть функцией (тогда ставятся скобки).</p>
20 <p>С объектом примерно также. Есть некоторый объект внутри переменной или константы, точка - вызов какого-то свойства, которое может быть функцией (тогда ставятся скобки).</p>
21 <p>Давайте договоримся, что в будущем мы будем говорить слово "<em>методы</em>", просто потому что так принято и все так делают во всем мире, на всех языках. При этом мы понимаем, что в JS - это просто функция, которая записана и лежит внутри определённого свойства с тем же именем.</p>
21 <p>Давайте договоримся, что в будущем мы будем говорить слово "<em>методы</em>", просто потому что так принято и все так делают во всем мире, на всех языках. При этом мы понимаем, что в JS - это просто функция, которая записана и лежит внутри определённого свойства с тем же именем.</p>
22 <p>JavaScript не является простым языком, когда мы говорим о понимании его внутренностей и глубоком понимании того, как он работает. На самом деле строчка - это примитивный тип, а не объект. Но если мы обратимся к строке напрямую, то все отработает также, как если бы она была записана в константу или переменную:</p>
22 <p>JavaScript не является простым языком, когда мы говорим о понимании его внутренностей и глубоком понимании того, как он работает. На самом деле строчка - это примитивный тип, а не объект. Но если мы обратимся к строке напрямую, то все отработает также, как если бы она была записана в константу или переменную:</p>
23 <p>Почему нет ошибки и строка начинает вести себя, как объект?</p>
23 <p>Почему нет ошибки и строка начинает вести себя, как объект?</p>
24 <p>Если простыми словами, то происходит какой-то некий процесс, который делает для вас прозрачным трансформацию в объект. Этот процесс называется<em>boxing</em>. То есть в тот момент, когда вы складываете в константу какой-то примитивный тип и после этого через точку к нему обращаетесь, то в этот момент JS за вас оборачивает этот примитивный тип в соответствующий объект, который связан с текущим примитивным типом и он начинает работать таким образом. После этого происходит его<em>unboxing</em>(разворачивание) и внутри всё равно оказывается примитивный тип. Этот механизм следует определённым целям и попозже мы разберёмся с ним чуть глубже.</p>
24 <p>Если простыми словами, то происходит какой-то некий процесс, который делает для вас прозрачным трансформацию в объект. Этот процесс называется<em>boxing</em>. То есть в тот момент, когда вы складываете в константу какой-то примитивный тип и после этого через точку к нему обращаетесь, то в этот момент JS за вас оборачивает этот примитивный тип в соответствующий объект, который связан с текущим примитивным типом и он начинает работать таким образом. После этого происходит его<em>unboxing</em>(разворачивание) и внутри всё равно оказывается примитивный тип. Этот механизм следует определённым целям и попозже мы разберёмся с ним чуть глубже.</p>
25 <h2>Тип данных: объект</h2>
25 <h2>Тип данных: объект</h2>
26 <p>В JavaScript есть отдельный тип данных, который называется объект и по сути любой объект, с которым мы работаем, является этим типом данных (точнее его подтипом, но об этом мы будем говорить позже, потому что сейчас мы сосредоточены больше на базовом понимании и связи с ООП, чем на особенностях работы JS).</p>
26 <p>В JavaScript есть отдельный тип данных, который называется объект и по сути любой объект, с которым мы работаем, является этим типом данных (точнее его подтипом, но об этом мы будем говорить позже, потому что сейчас мы сосредоточены больше на базовом понимании и связи с ООП, чем на особенностях работы JS).</p>
27 <p>Как же работает этот тип данных:</p>
27 <p>Как же работает этот тип данных:</p>
28 <p>Он представляет собой вот такую структуру, в которой мы задаём ограничители (фигурные скобки в начале и в конце), после этого описываем ключ и значение.</p>
28 <p>Он представляет собой вот такую структуру, в которой мы задаём ограничители (фигурные скобки в начале и в конце), после этого описываем ключ и значение.</p>
29 <p>Значением может быть всё что угодно. На вход ожидается любое выражение, после этого ставится запятая и дальше опять пара ключ-значение и тд. После этого в card у нас оказывается объект.</p>
29 <p>Значением может быть всё что угодно. На вход ожидается любое выражение, после этого ставится запятая и дальше опять пара ключ-значение и тд. После этого в card у нас оказывается объект.</p>
30 <p>Здесь начинается некоторая путаница, которую вводит JS и люди, которые знакомы только с этим языком часто смешивают это в одно и постоянно употребляют в разговоре. В свою очередь люди из других языков это не совсем понимают, потому что в других языках такая запись обозначает несколько иную вещь. К этому надо просто привыкнуть и всегда внутри у себя дифференцировать о чём мы говорим: о типе данных объект или объекте, как мы понимаем это с точки зрения ООП, хотя в каком-то смысле разница в JS стирается.</p>
30 <p>Здесь начинается некоторая путаница, которую вводит JS и люди, которые знакомы только с этим языком часто смешивают это в одно и постоянно употребляют в разговоре. В свою очередь люди из других языков это не совсем понимают, потому что в других языках такая запись обозначает несколько иную вещь. К этому надо просто привыкнуть и всегда внутри у себя дифференцировать о чём мы говорим: о типе данных объект или объекте, как мы понимаем это с точки зрения ООП, хотя в каком-то смысле разница в JS стирается.</p>
31 <h2>Как происходит обращение к объекту</h2>
31 <h2>Как происходит обращение к объекту</h2>
32 <p>Поскольку этот тип данных (объект) является и настоящим объектом в том числе, поэтому обращение к его ключам идёт, как обращение к обычным свойствам в объекте:</p>
32 <p>Поскольку этот тип данных (объект) является и настоящим объектом в том числе, поэтому обращение к его ключам идёт, как обращение к обычным свойствам в объекте:</p>
33 <p>Мы пишем card.key и получаем значение, всё довольно просто.</p>
33 <p>Мы пишем card.key и получаем значение, всё довольно просто.</p>
34 <p>Если мы обратимся к неизвестному свойству, то мы получим undefined.</p>
34 <p>Если мы обратимся к неизвестному свойству, то мы получим undefined.</p>
35 <p>Имеется в виду, что свойство не определено, хотя оно может быть определено и равно undefined, но обычно так не делают.</p>
35 <p>Имеется в виду, что свойство не определено, хотя оно может быть определено и равно undefined, но обычно так не делают.</p>
36 <p>Мы уже говорили, что определять самостоятельно undefined - неправильно, потому что вы просто не отличите определено оно или нет и что важно - вы не получаете ошибку. То есть, если вы где-то случайно (в JS легко это сделать, поскольку это динамический язык) допустите синтаксическую ошибку, то ваш код может продолжить работать, но продолжит работать с ошибками и при этом не упадёт. Это довольно опасная вещь, поэтому за этим надо следить.</p>
36 <p>Мы уже говорили, что определять самостоятельно undefined - неправильно, потому что вы просто не отличите определено оно или нет и что важно - вы не получаете ошибку. То есть, если вы где-то случайно (в JS легко это сделать, поскольку это динамический язык) допустите синтаксическую ошибку, то ваш код может продолжить работать, но продолжит работать с ошибками и при этом не упадёт. Это довольно опасная вещь, поэтому за этим надо следить.</p>
37 <p>У объектов в JS есть другой синтаксис. Вы всегда можете обратиться через квадратные скобки определив ключ, как строчку:</p>
37 <p>У объектов в JS есть другой синтаксис. Вы всегда можете обратиться через квадратные скобки определив ключ, как строчку:</p>
38 <p>Это позволяет, например, обращаться к свойствам, которые названы чуть сложнее, чем просто имена состоящие из алфавита английского языка. Например, если вы используете целое предложение, пробелы или какие-то специальные символы, то используйте такой способ обращения. Это не частый кейс, но такое бывает когда у вас объект динамический, то есть вы откуда-то собираете информацию - это будет достаточно удобно. Этот синтаксис ведёт себя точно также, если мы ошибаемся с ключом, то получаем undefined.</p>
38 <p>Это позволяет, например, обращаться к свойствам, которые названы чуть сложнее, чем просто имена состоящие из алфавита английского языка. Например, если вы используете целое предложение, пробелы или какие-то специальные символы, то используйте такой способ обращения. Это не частый кейс, но такое бывает когда у вас объект динамический, то есть вы откуда-то собираете информацию - это будет достаточно удобно. Этот синтаксис ведёт себя точно также, если мы ошибаемся с ключом, то получаем undefined.</p>
39 <h2>Что такое константа в JS</h2>
39 <h2>Что такое константа в JS</h2>
40 <p>Есть одна интересная деталь, которая уже может вводить в заблуждение. До этого момента мы привыкли, что константа обозначает реально константу и она никогда не меняется, но посмотрите внимательно на этот пример:</p>
40 <p>Есть одна интересная деталь, которая уже может вводить в заблуждение. До этого момента мы привыкли, что константа обозначает реально константу и она никогда не меняется, но посмотрите внимательно на этот пример:</p>
41 <p>Мы пишем card.wrongKey, который естественно пишет undefined, потому что он не определён, но после этого мы делаем присваивание (ничего не происходит, всё срабатывает молча) и после этого мы делаем снова вызов и получаем это значение.</p>
41 <p>Мы пишем card.wrongKey, который естественно пишет undefined, потому что он не определён, но после этого мы делаем присваивание (ничего не происходит, всё срабатывает молча) и после этого мы делаем снова вызов и получаем это значение.</p>
42 <p>И вот тут возникает 2 интересных момента:</p>
42 <p>И вот тут возникает 2 интересных момента:</p>
43 <ol><li>Объекты являются<em>mutable</em>, то есть изменяемыми, что может и не привычно после наших курсов, в которых мы всё делали неизменяемым, но JS - это классический императивный язык, в котором всё изменяемое и при этом с хорошими возможностями функционального программирования.</li>
43 <ol><li>Объекты являются<em>mutable</em>, то есть изменяемыми, что может и не привычно после наших курсов, в которых мы всё делали неизменяемым, но JS - это классический императивный язык, в котором всё изменяемое и при этом с хорошими возможностями функционального программирования.</li>
44 <li>Ключ поменял сам объект. И если до этого мы говорили про константу, как о чём-то, что нельзя менять, то получается что константа - это что-то, что можно менять.</li>
44 <li>Ключ поменял сам объект. И если до этого мы говорили про константу, как о чём-то, что нельзя менять, то получается что константа - это что-то, что можно менять.</li>
45 </ol><p>Возникает вопрос, а почему это константа?</p>
45 </ol><p>Возникает вопрос, а почему это константа?</p>
46 <p>Константа она только по той простой причине, что вы по имени card не можете записать какой-то объект целиком, то есть вы не можете заменить card полностью.</p>
46 <p>Константа она только по той простой причине, что вы по имени card не можете записать какой-то объект целиком, то есть вы не можете заменить card полностью.</p>
47 <p>Если вы перезапишите card чем-то новым (динамический язык позволяет это) - вы получите ошибку:</p>
47 <p>Если вы перезапишите card чем-то новым (динамический язык позволяет это) - вы получите ошибку:</p>
48 <blockquote><p>Кстати, так можно определять пустой объект const obj = {};</p>
48 <blockquote><p>Кстати, так можно определять пустой объект const obj = {};</p>
49 </blockquote><p>Но если вы меняете внутренности этого объекта, который вы положили в card, то всё будет работать.</p>
49 </blockquote><p>Но если вы меняете внутренности этого объекта, который вы положили в card, то всё будет работать.</p>
50 <p>У вас может оставаться какое-то странное ощущение, что константа не совсем константа, но какая-то определенная логика в этом тоже есть и к этому нужно просто привыкнуть. Этот момент будет детальнее разобран в следующем курсе JS: Коллекции.</p>
50 <p>У вас может оставаться какое-то странное ощущение, что константа не совсем константа, но какая-то определенная логика в этом тоже есть и к этому нужно просто привыкнуть. Этот момент будет детальнее разобран в следующем курсе JS: Коллекции.</p>
51 <h2>Объект с функциями</h2>
51 <h2>Объект с функциями</h2>
52 <p>Давайте посмотрим, как использовать наши объекты вместе с функциями.</p>
52 <p>Давайте посмотрим, как использовать наши объекты вместе с функциями.</p>
53 <p>Функции - это объекты первого рода.</p>
53 <p>Функции - это объекты первого рода.</p>
54 <blockquote><p>В данном случае под словом "объект" имеется в виду, как некоторая сущность в обычном понимании этого слова. Важно не путать это с ООП.</p>
54 <blockquote><p>В данном случае под словом "объект" имеется в виду, как некоторая сущность в обычном понимании этого слова. Важно не путать это с ООП.</p>
55 </blockquote><p>В объект (тип данных) мы можем записать любую функцию и пользоваться ей.</p>
55 </blockquote><p>В объект (тип данных) мы можем записать любую функцию и пользоваться ей.</p>
56 <p>Создаём карту и после этого вызываем name и damage.</p>
56 <p>Создаём карту и после этого вызываем name и damage.</p>
57 <p>name - статичное свойство, которое возвращает имя карты damage - вызов метода (на самом деле это свойство, внутри которого записана функция) куда передаётся значение здоровья.</p>
57 <p>name - статичное свойство, которое возвращает имя карты damage - вызов метода (на самом деле это свойство, внутри которого записана функция) куда передаётся значение здоровья.</p>
58 <p>Как видите, такой синтаксис выглядит приятнее, потому что это уже встроенный механизм, но по своему смыслу, семантике и результату действия - это абсолютно то же самое, что мы делали самостоятельно.</p>
58 <p>Как видите, такой синтаксис выглядит приятнее, потому что это уже встроенный механизм, но по своему смыслу, семантике и результату действия - это абсолютно то же самое, что мы делали самостоятельно.</p>
59 <h2>Создание объекта</h2>
59 <h2>Создание объекта</h2>
60 <p>Наши конструкторы и наши объекты превращаются в стандартный механизм, с которым мы работали.</p>
60 <p>Наши конструкторы и наши объекты превращаются в стандартный механизм, с которым мы работали.</p>
61 <p>У нас есть файл, который представляет из себя модуль. Он экспортирует некий конструктор, внутри которого мы теперь чуть-чуть проще реализуем всю нашу логику.</p>
61 <p>У нас есть файл, который представляет из себя модуль. Он экспортирует некий конструктор, внутри которого мы теперь чуть-чуть проще реализуем всю нашу логику.</p>
62 <p>Мы просто возвращаем объект, как тип данных, внутрь которого мы записываем переданные параметры: в name - имя, а в функцию damage мы передаём проценты исходя из которых будет считаться урон.</p>
62 <p>Мы просто возвращаем объект, как тип данных, внутрь которого мы записываем переданные параметры: в name - имя, а в функцию damage мы передаём проценты исходя из которых будет считаться урон.</p>
63 <p>С точки зрения интерфейсов ничего не меняется кроме варианта использования. То есть мы теперь не просто вызываем функцию и передаём туда строчку, а берём константу, пишем точку и обращаемся к какому-то свойству.</p>
63 <p>С точки зрения интерфейсов ничего не меняется кроме варианта использования. То есть мы теперь не просто вызываем функцию и передаём туда строчку, а берём константу, пишем точку и обращаемся к какому-то свойству.</p>
64 <h2>Динамическая диспетчеризация</h2>
64 <h2>Динамическая диспетчеризация</h2>
65 <p>Используя стандартный механизм мы получаем диспетчеризацию.</p>
65 <p>Используя стандартный механизм мы получаем диспетчеризацию.</p>
66 <p>Диспетчеризация происходит по имени свойства, потому что здесь выбор строится на основе объекта. То есть объект уже сам связан с какой-то конкретной функцией.</p>
66 <p>Диспетчеризация происходит по имени свойства, потому что здесь выбор строится на основе объекта. То есть объект уже сам связан с какой-то конкретной функцией.</p>
67 <p>На самом деле этот механизм чуть сложнее, просто сейчас нет смысла в это погружаться.</p>
67 <p>На самом деле этот механизм чуть сложнее, просто сейчас нет смысла в это погружаться.</p>
68 <p>В JS существует крайне важная концепция, он сильно отличается от многих ООП языков - это прототипы. Об этом мы поговорим позже, чтобы не вводить сейчас слишком много новой информации. Тем более она не имеет никакого значения к решаемым нами проблемам.</p>
68 <p>В JS существует крайне важная концепция, он сильно отличается от многих ООП языков - это прототипы. Об этом мы поговорим позже, чтобы не вводить сейчас слишком много новой информации. Тем более она не имеет никакого значения к решаемым нами проблемам.</p>