<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>JavaScript для тупых</title><author><name>JavaScript для тупых</name></author><id>https://teletype.in/atom/java-script-stupid</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/java-script-stupid?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@java-script-stupid?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=java-script-stupid"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/java-script-stupid?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-06-13T03:37:02.555Z</updated><entry><id>java-script-stupid:8AOVBrgl1</id><link rel="alternate" type="text/html" href="https://teletype.in/@java-script-stupid/8AOVBrgl1?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=java-script-stupid"></link><title>Promises (Обещания)</title><published>2020-05-22T16:16:28.351Z</published><updated>2020-05-22T16:16:28.351Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://teletype.in/files/f8/25/f825a4eb-80e0-4261-bad6-b19911a09338.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://teletype.in/files/6f/28/6f28658c-1e6f-401d-92b5-2beeb5660a8b.png&quot;&gt;Всем привет. На повестке сегодняшнего дня – Promises.</summary><content type="html">
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/6f/28/6f28658c-1e6f-401d-92b5-2beeb5660a8b.png&quot; width=&quot;1920&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Всем привет. На повестке сегодняшнего дня – &lt;code&gt;Promises&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;У многих возникает много непонимания как работать с обещаниями, а у многие даже не понимают зачем они вообще нужны. В этой статье, я, как и всегда, постараюсь максимально просто и на примерах рассказать о обещаниях. Надеюсь, что после прочтения этой статьи ты больше никогда не будешь прятаться от &lt;code&gt;Promises&lt;/code&gt;, ведь они совсем не страшные =)&lt;/p&gt;
  &lt;h3&gt;Начнем&lt;/h3&gt;
  &lt;p&gt;Хотелось бы начать с того, что JS язык синхронный, т.е. весь код выполняется последовательно. И все было бы хорошо, но достаточно быстро в языке появилась потребность в дополнительных возможностях, а именно, понадобилась асинхронность. Зачем?&lt;/p&gt;
  &lt;p&gt;Все мы сидим в социальных сетях. Когда ты заходишь, например, в Facebook, то наверное, замечал, что сайт загружается за несколько секунд, а не &amp;quot;висит&amp;quot; по несколько минут. Но все бы сайты, тем более такие крупные как Facebook без асинхронных операций загружались бы очень долго. &lt;/p&gt;
  &lt;p&gt;Ведь когда ты заходишь на Facebook – браузер отсылает очень много запросов на сервера соц.сети, чтобы получить какие-то данные, например, фотографию твоего профиля, информацию из этого профиля, личные сообщения, списки друзей и т.п. На все это нужно время, и если бы все эти запросы выполнялись друг за другом, т.е. каждый бы запрос ожидал завершения предыдущего – это был бы ад.&lt;/p&gt;
  &lt;p&gt;Благодаря асинхронности, все запросы отсылаются одновременно и весь остальной код не ждет ответа от них, а продолжает выполняться. Когда же асинхронная операция заканчивает свое выполнение – отрабатывает какая-либо заранее подготовленная функция, которая, например, отобразит блок с твоими друзьями или все сообщения в определенном диалоге.&lt;/p&gt;
  &lt;h3&gt;Какие асинхронные операции мы знаем?&lt;/h3&gt;
  &lt;p&gt;Я уже писал о асинхронных методах в JS, а конкретно: &lt;code&gt;setInterval&lt;/code&gt; и &lt;code&gt;setTimeout&lt;/code&gt;. &lt;/p&gt;
  &lt;p&gt;Это яркие представители асинхронного исполнения кода. Если не читал о них, то советую прочитать (делай тык):&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;&lt;code&gt;&lt;a href=&quot;https://teletype.in/@java-script-stupid/X8ICeCrVY&quot; target=&quot;_blank&quot;&gt;setInterval&lt;/a&gt;&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;&lt;a href=&quot;https://teletype.in/@java-script-stupid/X8ICeCrVY&quot; target=&quot;_blank&quot;&gt;setTimeout&lt;/a&gt;&lt;/code&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3&gt;Эмуляция работы с сервером с помощью setTimeout&lt;/h3&gt;
  &lt;p&gt;Итак, давай попробуем сэмулировать работу с сервером. Сначала, сделаем это с помощью &lt;code&gt;setTimeout&lt;/code&gt;, а затем с помощью &lt;code&gt;Promise&lt;/code&gt; и, как итог, поймем в чем разница и рассмотрим все плюсы &lt;code&gt;Promise&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;Представим, что мы отсылаем запрос на сервер. Сервер собирает данные (на это уходит какое-то время) и сервер высылает нам данные (это тоже занимает время).&lt;/p&gt;
  &lt;p&gt;Пошли к коду:&lt;/p&gt;
  &lt;pre&gt;console.log(&amp;#x27;Отправляем запрос на сервер...&amp;#x27;);

setTimeout(function() {
   console.log(&amp;#x27;Сервер собирает данные...&amp;#x27;);

   const data = {
     text: &amp;#x27;Данные с сервера&amp;#x27;
   };

  setTimeout(function() {
    data.other = true;
    console.log(&amp;#x27;Данные, которые предоставил сервер: &amp;#x27;, data);
  }, 2000);
}, 1500);&lt;/pre&gt;
  &lt;p&gt;Итак, весь процесс нашей эмуляции:&lt;/p&gt;
  &lt;ol&gt;
    &lt;li&gt;Эмулируем  отправку запроса&lt;/li&gt;
    &lt;li&gt;Создаем первый &lt;code&gt;setTimeout&lt;/code&gt;, который отработает через 1.5 секунды. Этот таймаут будет эмулировать &amp;quot;сбор данных&amp;quot; и создавать объект &lt;code&gt;data&lt;/code&gt; с этими данными.&lt;/li&gt;
    &lt;li&gt;Внутри первого &lt;code&gt;setTimeout&lt;/code&gt; создаем второй. Он будет как-то дополнять/изменять объект &lt;code&gt;data&lt;/code&gt; и как бы высылать пользователю и потратит он на это 2 секунды.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p&gt;Итог работы:&lt;/p&gt;
  &lt;figure class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/e9/e2/e9e2b06f-02ee-4676-8779-a9e413b69e97.png&quot; width=&quot;647&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Все прикольно. Отработало это ровно так как и ожидали за 3.5 секунды.&lt;/p&gt;
  &lt;p&gt;Вроде бы все прикольно, да не совсем. Мне лично, даже смотреть на такой код больно. &lt;code&gt;setTimeout&lt;/code&gt; в &lt;code&gt;setTimeout&lt;/code&gt;-е. Ведь если мы сейчас захотим еще что-то эмулировать, то у нас будет еще одна вложенность и все это будет напоминать матрешку. Разбираться в таких &amp;quot;матрешках&amp;quot; – не самое приятное удовольствие.&lt;/p&gt;
  &lt;p&gt;Поэтому, давай попробуем все это же провернуть с помощью &lt;code&gt;Promise&lt;/code&gt;.&lt;/p&gt;
  &lt;h3&gt;Эмуляция работы с сервером с помощью Promise&lt;/h3&gt;
  &lt;p&gt;Сначала создадим пустой &lt;code&gt;Promise&lt;/code&gt;. Делается это так:&lt;/p&gt;
  &lt;pre&gt;const promise = new Promise(function(resolve, reject) {});&lt;/pre&gt;
  &lt;p&gt;Создается обещание с помощью класса &lt;code&gt;Promise&lt;/code&gt;, поэтому используется ключевое слово &lt;code&gt;new&lt;/code&gt;. В конструктор данного класса передается всего один аргумент –&lt;code&gt;callback&lt;/code&gt;-функция, которая, в свою очередь, принимает в себя 2 аргумента:&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;&lt;code&gt;resolve&lt;/code&gt; (переводится как &amp;quot;разрешить&amp;quot;)&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;reject&lt;/code&gt; (переводится как &amp;quot;отклонить&amp;quot;)&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;Эти аргументы, на самом деле являются функциями. Благодаря этим 2-ум функциям мы можем контролировать выполнение &lt;code&gt;Promise&lt;/code&gt;. К примеру, внутри обещания у нас будут какие-то проверки. Если все проверки будут выполнены удачно, то мы вызовем функцию &lt;code&gt;resolve&lt;/code&gt; и, в таком случае, &lt;code&gt;Promise&lt;/code&gt; завершится удачно. А если же, какая-то проверка не будет пройдена, то мы сможем завершить работу &lt;code&gt;Promise&lt;/code&gt; с помощью вызова функции &lt;code&gt;reject&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;Пока что, скорее всего совсем ничего не понятно. Но, сейчас, мы разберемся со всем этим делом, не переживай.&lt;/p&gt;
  &lt;p&gt;Сейчас мы сделаем ту же самую эмуляцию работы с сервером с помощью &lt;code&gt;Promise&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;Мы уже создали обещание, но оно еще никак не функционирует. Поэтому, давай переносить функционал из кода написанного ранее.&lt;/p&gt;
  &lt;pre&gt;console.log(&amp;#x27;Отправляем запрос на сервер...&amp;#x27;);

const promise = new Promise(function(resolve, reject) {
  setTimeout(function() {
    const data = {
     text: &amp;#x27;Данные с сервера&amp;#x27;
    };
  }, 2000);
});&lt;/pre&gt;
  &lt;p&gt;Итак, внутри &lt;code&gt;callback&lt;/code&gt;-функции нашего &lt;code&gt;Promise&lt;/code&gt;, мы разместили код:&lt;/p&gt;
  &lt;pre&gt;setTimeout(function() {
    const data = {
     text: &amp;#x27;Данные с сервера&amp;#x27;
    };
}, 2000);&lt;/pre&gt;
  &lt;p&gt;Это код нашего первого &lt;code&gt;setTimeout&lt;/code&gt; из кода выше. Давай добавим в этот &lt;code&gt;setTimeout&lt;/code&gt; вызов функции &lt;code&gt;resolve()&lt;/code&gt;, так как мы хотим чтобы наш &lt;code&gt;Promise&lt;/code&gt; выполнился без ошибок. В итоге получаем такой код:&lt;/p&gt;
  &lt;pre&gt;const promise = new Promise(function(resolve, reject) {
  setTimeout(function() {
    console.log(&amp;#x27;Сервер собирает данные...&amp;#x27;);
    const data = {
     text: &amp;#x27;Данные с сервера&amp;#x27;
    };

    resolve(); //успешное выполнение Promise
  }, 1500);
});&lt;/pre&gt;
  &lt;p&gt;Итак, как работать с этим всем дальше? У callback-функции &lt;code&gt;Promise&lt;/code&gt;, как я и написал ранее существует две функции: &lt;code&gt;resolve&lt;/code&gt;, &lt;code&gt;reject&lt;/code&gt;. &lt;/p&gt;
  &lt;p&gt;Вызвав функцию &lt;code&gt;resolve&lt;/code&gt; в коде выше, мы, как бы послали сигнал, что &lt;code&gt;Promise&lt;/code&gt; успешно выполнился. Но как отловить этот сигнал? На самом деле в этом нет ничего сложно. &lt;/p&gt;
  &lt;p&gt;В константу &lt;code&gt;promise&lt;/code&gt; мы записали наш &lt;code&gt;Promise&lt;/code&gt;, поэтому мы можем работать с ней следующим образом: &lt;/p&gt;
  &lt;pre&gt;promise.then(function() {
  console.log(&amp;#x27;Успешное выполнение Promise&amp;#x27;);
});&lt;/pre&gt;
  &lt;p&gt;Но, в целом, в этом случае (как и во многих других) лучше использовать стрелочную функцию в качестве callback:&lt;/p&gt;
  &lt;pre&gt;promise.then(() =&amp;gt; console.log(&amp;#x27;Успешное выполнение Promise&amp;#x27;));&lt;/pre&gt;
  &lt;p&gt;У &lt;code&gt;Promise&lt;/code&gt; существует метод &lt;code&gt;then&lt;/code&gt;, который ожидает, что в него ты передашь callback-функцию, которая выполнится только в тот момент, когда внутри самого &lt;code&gt;Promise&lt;/code&gt; мы вызовем функцию &lt;code&gt;resolve&lt;/code&gt;, которая означает успешное выполнение обещания.&lt;/p&gt;
  &lt;p&gt;Итог работы нашего кода:&lt;/p&gt;
  &lt;figure class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/04/8f/048fbd60-0934-4ae9-b364-7458847a15bc.png&quot; width=&quot;290&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Итак, первую часть мы реализовали с помощью &lt;code&gt;Promise&lt;/code&gt;. Пока что непонятно, чем же &lt;code&gt;Promise&lt;/code&gt; лучше и в чем их профит. Но давай продолжим перетаскивать код дальше.&lt;/p&gt;
  &lt;p&gt;На самом деле, третьим сообщением, в соответствии с первой реализацией эмуляции должен выводится текст: &amp;quot;Данные, которые предоставил сервер...&amp;quot; и дополнительно должен выводится сам объект &lt;code&gt;data&lt;/code&gt;, а не &amp;quot;Успешное выполнение Promise&amp;quot;. Давай это поправим, поэтому вернемся к этой строке:&lt;/p&gt;
  &lt;pre&gt;promise.then(() =&amp;gt; console.log(&amp;#x27;Успешное выполнение Promise&amp;#x27;));&lt;/pre&gt;
  &lt;p&gt;Итак, здесь мы должны заменить текст и вывести объект &lt;code&gt;data&lt;/code&gt;. Но вот в чем проблема – здесь, в этой &lt;code&gt;callback&lt;/code&gt;-функции у нас нет никакого объекта &lt;code&gt;data&lt;/code&gt;, следственно вывести мы его не можем. Чтобы решить этот вопрос и получить доступ к объекту &lt;code&gt;data&lt;/code&gt; нужно всего лишь в метод &lt;code&gt;resolve&lt;/code&gt;, который мы вызываем в &lt;code&gt;Promise&lt;/code&gt; передать наш объект &lt;code&gt;data&lt;/code&gt;. Вернемся к нашему коду и поправим вызов &lt;code&gt;resolve&lt;/code&gt;:&lt;/p&gt;
  &lt;pre&gt;const promise = new Promise(function(resolve, reject) {
  setTimeout(function() {
    console.log(&amp;#x27;Сервер собирает данные...&amp;#x27;);
    const data = {
     text: &amp;#x27;Данные с сервера&amp;#x27;
    };

    resolve(data); //передаем data
  }, 1500);
});&lt;/pre&gt;
  &lt;p&gt;Теперь в функцию &lt;code&gt;resolve&lt;/code&gt; мы передаем наш объект &lt;code&gt;data&lt;/code&gt;. Что же это нам дает? А дает это нам возможность получить этот объект в методе &lt;code&gt;then&lt;/code&gt;. И вот как это делается.&lt;/p&gt;
  &lt;p&gt;Вот это:&lt;/p&gt;
  &lt;pre&gt;promise.then(() =&amp;gt; console.log(&amp;#x27;Успешное выполнение Promise&amp;#x27;));&lt;/pre&gt;
  &lt;p&gt;Меняем на:&lt;/p&gt;
  &lt;pre&gt;promise.then(data =&amp;gt; 
  console.log(&amp;#x27;Данные, которые предоставил сервер: &amp;#x27;, data)
);&lt;/pre&gt;
  &lt;p&gt;Как видишь, теперь у нас стрелочная функция имеет аргумент &lt;code&gt;data&lt;/code&gt; – и в этот аргумент и попадает то, что мы передаем внутрь функции &lt;code&gt;resolve&lt;/code&gt; при ее вызове. &lt;/p&gt;
  &lt;p&gt;Как итог, получаем:&lt;/p&gt;
  &lt;figure class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/93/fc/93fc2ec1-4ff6-4fb1-b6df-7b7cae1618ce.png&quot; width=&quot;548&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;И все бы хорошо, да вот только объект в итоге имеет совсем не тот итоговый вид, как в первом случае.&lt;/p&gt;
  &lt;p&gt;На данный момент мы перенесли только один &lt;code&gt;setTimeout&lt;/code&gt;, а у нас их было два.&lt;/p&gt;
  &lt;p&gt;Во-втором &lt;code&gt;setTimeout&lt;/code&gt; мы добавляли дополнительно поле &lt;code&gt;other&lt;/code&gt; со значением &lt;code&gt;true&lt;/code&gt; к нашему объекту &lt;code&gt;data&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;Получается, что мы пропустили момент модификации объекта. Давай восполним данную потерю.&lt;/p&gt;
  &lt;p&gt;Нам нужно в какой-то момент модифицировать объект &lt;code&gt;data&lt;/code&gt; и добавить ему свойство &lt;code&gt;other&lt;/code&gt;. Когда же нам это сделать? Сделать нам это нужно тут:&lt;/p&gt;
  &lt;pre&gt;promise.then(data =&amp;gt; 
  console.log(&amp;#x27;Данные, которые предоставил сервер: &amp;#x27;, data)
);&lt;/pre&gt;
  &lt;p&gt;Вместо того, чтобы просто выполнить &lt;code&gt;console.log&lt;/code&gt;, нам нужно изменить объект &lt;code&gt;data&lt;/code&gt;, который приходит к нам из &lt;code&gt;resolve&lt;/code&gt; выполненного в &lt;code&gt;Promise&lt;/code&gt;.  Более того, нам нужно выполнить это только через 2 секунды, а это значит, что нам нужно добавить наш &lt;code&gt;setTimeout&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;Давай попробуем исправить наш код:&lt;/p&gt;
  &lt;pre&gt;promise.then(data =&amp;gt; 
  setTimeout(function() {
     data.other = true;
     console.log(&amp;#x27;Данные, которые предоставил сервер: &amp;#x27;, data);
  }, 2000)
);&lt;/pre&gt;
  &lt;p&gt;Итог:&lt;/p&gt;
  &lt;figure class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/e2/fd/e2fd0d65-d158-4b1d-98bb-d0a4ab34e79c.png&quot; width=&quot;647&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;И вот, вроде бы уже и можно вскрикнуть &amp;quot;Ура&amp;quot;. Но, нет. На самом деле, мы схалтурили. &lt;/p&gt;
  &lt;p&gt;Первый &lt;code&gt;setTimeout&lt;/code&gt;, мы реализовали внутри &lt;code&gt;Promise&lt;/code&gt;, что обеспечило нам контроль над происходящим: можем вызвать &lt;code&gt;resolve&lt;/code&gt; для того, чтобы указать на успешное выполнение и &lt;code&gt;reject&lt;/code&gt; – на выполнение с ошибкой.&lt;/p&gt;
  &lt;p&gt;Сейчас же, наш второй &lt;code&gt;setTimeout&lt;/code&gt; не имеет такой возможности. А все потому, что мы не использовали &lt;code&gt;Promise&lt;/code&gt;. Давай используем его и поправим наш имеющийся код. Для того, чтобы добавить &lt;code&gt;Promise&lt;/code&gt;, нам нужно, чтобы &lt;code&gt;callback&lt;/code&gt;-функция, которую мы определяем внутри &lt;code&gt;then&lt;/code&gt; – возвращала нам новый &lt;code&gt;Promise.&lt;/code&gt; Поэтому давай снова изменим &lt;code&gt;callback&lt;/code&gt;-функцию в &lt;code&gt;then&lt;/code&gt;:&lt;/p&gt;
  &lt;pre&gt;promise.then(data =&amp;gt; new Promise(function(resolve, reject) {}));&lt;/pre&gt;
  &lt;p&gt;Теперь мы сделали так, что &lt;code&gt;then&lt;/code&gt; вернет нам новый &lt;code&gt;Promise&lt;/code&gt;. Пока что он ничего не выполняет, поэтому давай добавим наш &lt;code&gt;setTimeout&lt;/code&gt; в тело &lt;code&gt;callback&lt;/code&gt;-функции нашего нового &lt;code&gt;Promise&lt;/code&gt;:&lt;/p&gt;
  &lt;pre&gt;promise.then(data =&amp;gt; new Promise(function(resolve, reject) {  
  setTimeout(function() {
     data.other = true;
     
     //не забываем выполнять resolve(data)
     resolve(data);
  }, 2000)
}));&lt;/pre&gt;
  &lt;p&gt;Этим этапом мы изменили наш объект &lt;code&gt;data&lt;/code&gt;. И с помощью &lt;code&gt;resolve(data)&lt;/code&gt; мы сообщили, что наш новый (второй) &lt;code&gt;Promise&lt;/code&gt; выполнился успешно и передали наш объект &lt;code&gt;data&lt;/code&gt; дальше.&lt;/p&gt;
  &lt;p&gt;Но мы еще не выводим сообщение о том, что сервер предоставил нам какие-то данные. Давай поправим и это. Так как у нас из &lt;code&gt;then&lt;/code&gt; возвращается новый &lt;code&gt;Promise&lt;/code&gt;, то это означает, что мы можем использовать тот же метод &lt;code&gt;then&lt;/code&gt; к этому обещанию  и как-то отреагировать на новый вызов &lt;code&gt;resolve(data)&lt;/code&gt;:&lt;/p&gt;
  &lt;pre&gt;promise.then(data =&amp;gt; 
  new Promise(function(resolve, reject) {  
    setTimeout(function() {
       data.other = true;
     
       //не забываем выполнять resolve(data)
       resolve(data);
    }, 2000)
  })
).then(data =&amp;gt;
  console.log(&amp;#x27;Данные, которые предоставил сервер: &amp;#x27;, data)
);&lt;/pre&gt;
  &lt;p&gt;И вот теперь у нас все выполняется абсолютно так, как нужно. &lt;/p&gt;
  &lt;p&gt;Итак, весь наш код выглядит так:&lt;/p&gt;
  &lt;figure class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/1f/f6/1ff67141-8632-4136-a5b0-70563c725247.png&quot; width=&quot;587&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;По количеству строк, относительно изначальной реализации – кода прибавилось. Но если задуматься, то в первой нашей реализации мы никак не управляли состоянием выполнения и не могли на него повлиять. &lt;/p&gt;
  &lt;p&gt;С &lt;code&gt;Promise&lt;/code&gt; же, мы имеем контроль над выполнением нашего кода. Если код успешно выполнился, то мы выполняем функцию &lt;code&gt;resolve&lt;/code&gt; и обработчик &lt;code&gt;then&lt;/code&gt; сразу же отлавливает это и выполняет заданные нами действия. Это же круто? Безусловно.&lt;/p&gt;
  &lt;p&gt;Но, мы пока что не затронули метод &lt;code&gt;reject&lt;/code&gt;. Поэтому, давай поговорим и о нем.&lt;/p&gt;
  &lt;h3&gt;Метод reject&lt;/h3&gt;
  &lt;p&gt;Говорим и говорим о &lt;code&gt;resolve&lt;/code&gt;, а &lt;code&gt;reject&lt;/code&gt; как-будто, вообще никто и звать никак.&lt;/p&gt;
  &lt;p&gt;На самом деле метод &lt;code&gt;reject&lt;/code&gt; не менее полезный, но служит он для той цели, чтобы сообщить о том, что наш &lt;code&gt;Promise&lt;/code&gt; должен завершиться ошибкой.&lt;/p&gt;
  &lt;p&gt;Ты уже знаешь, что обработчиком выполнения функции &lt;code&gt;resolve&lt;/code&gt; служит метод &lt;code&gt;then&lt;/code&gt;. &lt;/p&gt;
  &lt;p&gt;У функции &lt;code&gt;reject&lt;/code&gt;, свой обработчик – &lt;code&gt;catch&lt;/code&gt;. &lt;/p&gt;
  &lt;p&gt;Если посмотреть еще раз на последний скриншот с кодом, то можно заметить, что &lt;code&gt;Promise&lt;/code&gt; создают цепочку вызовов методов &lt;code&gt;then&lt;/code&gt;:&lt;/p&gt;
  &lt;pre&gt;const promise = new Promise(...);

promise.then(
... код ...
).then(
... код ...
)&lt;/pre&gt;
  &lt;p&gt;Так вот, во всей этой цепочке, методу &lt;code&gt;catch&lt;/code&gt; самое место – практически в самом ее конце (почему практически – узнаешь дальше):&lt;/p&gt;
  &lt;pre&gt;const promise = new Promise(...);

promise.then(
... код ...
).then(
... код ...
).catch(
 ...обработка ошибки...
)&lt;/pre&gt;
  &lt;p&gt;Внутри этого &lt;code&gt;catch&lt;/code&gt; мы можем каким-то образом обработать ошибку и как и с функцией &lt;code&gt;resolve&lt;/code&gt;, мы можем передать эту самую ошибку в качестве аргумента функции &lt;code&gt;reject(error)&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;Для примера, я поменяю в нашем коде один из &lt;code&gt;resolve&lt;/code&gt; на &lt;code&gt;reject&lt;/code&gt; и передам в качестве аргумента ошибку:&lt;/p&gt;
  &lt;pre&gt;const promise = new Promise(function(resolve, reject) {
  setTimeout(function() {
    console.log(&amp;#x27;Сервер собирает данные...&amp;#x27;);
    const data = {
     text: &amp;#x27;Данные с сервера&amp;#x27;
    };

    reject(new Error(&amp;#x27;Ошибка сбора данных&amp;#x27;)); //передаем ошибку
  }, 1500);
});

promise.then(data =&amp;gt; 
  new Promise(function(resolve, reject) {  
    setTimeout(function() {
       data.other = true;
     
       //не забываем выполнять resolve(data)
       resolve(data);
    }, 2000)
  })
).then(data =&amp;gt;
  console.log(&amp;#x27;Данные, которые предоставил сервер: &amp;#x27;, data)
).catch(err =&amp;gt; console.error(err));&lt;/pre&gt;
  &lt;p&gt;Все что мы сделали – это вызвали &lt;code&gt;reject&lt;/code&gt; и навесили обработчик &lt;code&gt;catch&lt;/code&gt;. И теперь, если запустить наш код, мы получим ошибку:&lt;/p&gt;
  &lt;figure class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/2d/33/2d331f38-6f55-44c4-9cd7-d75ca7075c32.png&quot; width=&quot;680&quot; /&gt;
  &lt;/figure&gt;
  &lt;h3&gt;Метод finally&lt;/h3&gt;
  &lt;p&gt;Кроме методов &lt;code&gt;then&lt;/code&gt; и &lt;code&gt;catch&lt;/code&gt;, существует еще один метод – &lt;code&gt;finally&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;Метод &lt;code&gt;finally&lt;/code&gt; выполняется всегда, вне зависимости от того вызвали мы внутри обещания &lt;code&gt;resolve&lt;/code&gt; или &lt;code&gt;reject&lt;/code&gt;.  &lt;/p&gt;
  &lt;p&gt;Этот метод мы размещаем в самом конце цепочки и итоговый код у нас получается таким:&lt;/p&gt;
  &lt;pre&gt;const promise = new Promise(function(resolve, reject) {
  setTimeout(function() {
    console.log(&amp;#x27;Сервер собирает данные...&amp;#x27;);
    const data = {
     text: &amp;#x27;Данные с сервера&amp;#x27;
    };

    resolve(data);
    
    //генерируем ошибку
    //reject(new Error(&amp;#x27;Ошибка сбора данных&amp;#x27;));
  }, 1500);
});

promise.then(data =&amp;gt; 
  new Promise(function(resolve, reject) {  
    setTimeout(function() {
       data.other = true;
     
       //не забываем выполнять resolve(data)
       resolve(data);
    }, 2000)
  })
).then(data =&amp;gt;
  console.log(&amp;#x27;Данные, которые предоставил сервер: &amp;#x27;, data)
).catch(err =&amp;gt; 
  console.error(err)
).finally(() =&amp;gt; 
  console.log(&amp;#x27;Работа с сервером завершена&amp;#x27;)
);&lt;/pre&gt;
  &lt;p&gt;&lt;code&gt;finally&lt;/code&gt; действительно не важно, будет ошибка:&lt;/p&gt;
  &lt;figure class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/17/e2/17e2f96b-9136-46fa-9dc4-5c71e1534eae.png&quot; width=&quot;674&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;или ее не будет:&lt;/p&gt;
  &lt;figure class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/6b/90/6b90184c-3561-402a-8404-84e9c180b91a.png&quot; width=&quot;258&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Он будет выполняться всегда.&lt;/p&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;h2&gt;Домашка&lt;/h2&gt;
  &lt;p&gt;Итак, домашнее задание придумать не просто. Поэтому, я оставлю листинг кода в онлайн-редакторе, попробуй поиграться сам с кодом и разобраться, если какие-то моменты остались недопонятыми. Ну, и, конечно же, если совсем будет много вопросов – всегда можешь писать в наш чат (ссылка на него в группе, в закрепленном сообщении).&lt;/p&gt;
  &lt;p&gt; &lt;a href=&quot;https://repl.it/@JSstupid/promises&quot; target=&quot;_blank&quot;&gt;Ссылка на код&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>java-script-stupid:DH4eLd2VF</id><link rel="alternate" type="text/html" href="https://teletype.in/@java-script-stupid/DH4eLd2VF?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=java-script-stupid"></link><title>Прототипы</title><published>2020-05-14T13:35:40.432Z</published><updated>2020-05-14T15:25:00.572Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://teletype.in/files/de/5b/de5b9eaa-0e3b-4181-b5e9-32463e28b746.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://teletype.in/files/aa/1b/aa1bc674-3b76-4a2e-8413-b40d264e6169.png&quot;&gt;Сегодня речь пойдет о прототипах. Чтобы лучше все понять – создаем сразу же простой объект.</summary><content type="html">
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/aa/1b/aa1bc674-3b76-4a2e-8413-b40d264e6169.png&quot; width=&quot;1920&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Сегодня речь пойдет о прототипах. Чтобы лучше все понять – создаем сразу же простой объект.&lt;/p&gt;
  &lt;pre&gt;const cat = {
    name: &amp;#x27;Кот&amp;#x27;,
    weight: 3,
    meow: function() {
      console.log(&amp;#x27;meow&amp;#x27;);
    }
};

console.log(cat);&lt;/pre&gt;
  &lt;p&gt;Результат:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/05/c7/05c77cf2-3041-4e03-b1c6-3cc5175c693e.png&quot; width=&quot;690&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Попробуем вывести в консоль результат действия функции &lt;code&gt;meow&lt;/code&gt;:&lt;/p&gt;
  &lt;pre&gt;console.log(cat.meow()); //выведет строку: meow&lt;/pre&gt;
  &lt;p&gt;Все логично и просто. Попробуем вызвать несуществующую функцию:&lt;/p&gt;
  &lt;pre&gt;cat.woof();&lt;/pre&gt;
  &lt;p&gt;Результат ожидаем:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/7d/88/7d8825c9-40d7-4dbb-9e47-e853a7a2131f.png&quot; width=&quot;734&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;JavaScript правильно подсказывает – &lt;code&gt;woof&lt;/code&gt; не является функцией. Оно так и есть, ведь мы не определяли эту функцию внутри нашего объекта.&lt;/p&gt;
  &lt;p&gt;Но, для примера,  давай попробуем вызвать еще один метод, который мы не определяли:&lt;/p&gt;
  &lt;pre&gt;cat.valueOf();&lt;/pre&gt;
  &lt;p&gt;Результат:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/06/b9/06b986ca-a10a-4b76-8738-99e7333b828b.png&quot; width=&quot;538&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Ошибки не произошло. И даже вывелись все данные о нашем объекте. &lt;/p&gt;
  &lt;p&gt;Попробуем еще: &lt;/p&gt;
  &lt;pre&gt;cat.toString();&lt;/pre&gt;
  &lt;p&gt;Результат:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/90/db/90db7dc7-6cfa-4319-b116-84144819282d.png&quot; width=&quot;302&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Снова что-то вывелось и снова никакой ошибки. Но как так? &lt;/p&gt;
  &lt;p&gt;Мы не определяли никакого метода &lt;code&gt;valueOf&lt;/code&gt; внутри нашего объекта, ровно как и не определяли метод &lt;code&gt;toString&lt;/code&gt;. Магия вне Хогвартса? Нет. Все куда проще.&lt;/p&gt;
  &lt;p&gt;Еще раз посмотрим на первый скриншот в этой статье:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/52/5c/525c05a6-d054-41e0-89b1-378866f42dc8.png&quot; width=&quot;690&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Это наш объект. Показаны все свойства и методы, которые мы определяли: &lt;code&gt;meow&lt;/code&gt;, &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;weight&lt;/code&gt;. &lt;/p&gt;
  &lt;p&gt;Но что за свойство &lt;code&gt;__proto__&lt;/code&gt;? Давай посмотрим, что лежим внутри него:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/55/c3/55c36018-87e0-4811-88be-9ca9f5758117.png&quot; width=&quot;866&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Очень много всего. Непонятно зачем, а главное – непонятно откуда.&lt;/p&gt;
  &lt;p&gt;В этом всем списке, мы видим и те методы, которые мы вызывали: &lt;code&gt;valueOf&lt;/code&gt; и &lt;code&gt;toString&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;Когда мы вызывали данные методы, JavaScript искал их сначала в пределах нашего объекта, а так как там он их не нашел, то пошел искать их в свойство &lt;code&gt;__proto__&lt;/code&gt;.&lt;/p&gt;
  &lt;h3&gt;Как это работает и зачем нужно?&lt;/h3&gt;
  &lt;p&gt;Давай сначала разберемся с созданием объекта. Тот синтаксис, который мы использовали для определения нашего объекта &lt;code&gt;cat&lt;/code&gt; является упрощенным:&lt;/p&gt;
  &lt;pre&gt;const cat = {
    name: &amp;#x27;Кот&amp;#x27;,
    weight: 3,
    meow: function() {
      console.log(&amp;#x27;meow&amp;#x27;);
    }
};&lt;/pre&gt;
  &lt;p&gt;Мы можем определить это другим методом, тем, который более понятен для самого JavaScript и в который, в любом случае, JS приводит наш метод определения:&lt;/p&gt;
  &lt;pre&gt;const cat = new Object({
    name: &amp;#x27;Кот&amp;#x27;,
    weight: 3,
    meow: function() {
      console.log(&amp;#x27;meow&amp;#x27;);
    }
});&lt;/pre&gt;
  &lt;p&gt;Т.е. создается новый объект типа &lt;code&gt;Object&lt;/code&gt; используя ключевое слово &lt;code&gt;new&lt;/code&gt;. И внутрь этого &lt;code&gt;Object&lt;/code&gt; мы передаем наш объект. В результате, ничего абсолютно не меняется. Попробуем вывести объект cat в консоль:&lt;/p&gt;
  &lt;pre&gt;console.log(cat);&lt;/pre&gt;
  &lt;p&gt;Результат:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/30/e5/30e5a24e-ce07-4a4b-9599-359cbd097fc9.png&quot; width=&quot;588&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Как видишь, мы поменяли метод инициализации нашего объекта, но абсолютно ничего не поменялось в итоговом результате.&lt;/p&gt;
  &lt;p&gt;Так как мы создаем все наши объекты используя эту конструкцию &lt;code&gt;new Object(...)&lt;/code&gt;, то от этого самого &lt;code&gt;Object&lt;/code&gt; к нашему объекту добавляются дополнительные свойства. К которым и относится то самое, непонятно откуда взявшееся, до текущего момента, свойство &lt;code&gt;__proto__&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;Получается, все объекты, которые мы создаем основываются на базовом классе JS - &lt;code&gt;Object&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;У класса &lt;code&gt;Object&lt;/code&gt; имеется свойство &lt;code&gt;prototype&lt;/code&gt;. Посмотрим, что там внутри:&lt;/p&gt;
  &lt;pre&gt;console.log(Object.prototype);&lt;/pre&gt;
  &lt;p&gt;Результат:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/8e/a8/8ea82b07-9c84-4a4e-adef-03da483669c3.png&quot; width=&quot;1504&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;И мы видим, что внутри этого свойства лежат те же методы, которые добавились к нашему объекту в свойство &lt;code&gt;__proto__&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;Теперь, примерно объясню, зачем это нужно и как это можно использовать.&lt;/p&gt;
  &lt;p&gt;Давай в свойство &lt;code&gt;prototype&lt;/code&gt; класса &lt;code&gt;Object&lt;/code&gt; добавим какую-нибудь свою функцию. К примеру, функцию &lt;code&gt;woof&lt;/code&gt;, которую мы пытались вызывать и у нашего объекта, но у нас происходила ошибка:&lt;/p&gt;
  &lt;pre&gt;Object.prototype.woof = function() {
    console.log(&amp;#x27;woof&amp;#x27;);
}&lt;/pre&gt;
  &lt;p&gt;Теперь, ничего не меняя в нашем объекте, т.е. он останется такого же вида:&lt;/p&gt;
  &lt;pre&gt;const cat = new Object({
    name: &amp;#x27;Кот&amp;#x27;,
    weight: 3,
    meow: function() {
      console.log(&amp;#x27;meow&amp;#x27;);
    }
});&lt;/pre&gt;
  &lt;p&gt;Попробуем вызвать метод woof:&lt;/p&gt;
  &lt;pre&gt;console.log(cat.woof());&lt;/pre&gt;
  &lt;p&gt;Результат:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/54/45/5445aa74-210d-4c86-8501-1827bdf11452.png&quot; width=&quot;370&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Как видишь, никакой ошибки и все прекрасно отработало. Еще раз посмотрим на наш объект в консоли:&lt;/p&gt;
  &lt;pre&gt;console.log(cat);&lt;/pre&gt;
  &lt;p&gt;Результат:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/85/1d/851db89a-4b7a-4a7e-83e4-5664c4d148fb.png&quot; width=&quot;738&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Метод &lt;code&gt;woof&lt;/code&gt;, который мы добавляли в свойство &lt;code&gt;prototype&lt;/code&gt; объекта &lt;code&gt;Object&lt;/code&gt; успешно передалось в свойство &lt;code&gt;__proto__&lt;/code&gt; нашего объекта, поэтому и не произошло никакой ошибки.&lt;/p&gt;
  &lt;p&gt;Естественно, даже если мы будем использовать первоначальный синтаксис создания нашего объекта без использования &lt;code&gt;new Object(...)&lt;/code&gt;, то все равно все будет работать ровно так же.&lt;/p&gt;
  &lt;p&gt;Надеюсь, ты уже понял, что с помощью прототипов мы получаем возможность расширять возможности наших объектов. К примеру, если оставить данный метод:&lt;/p&gt;
  &lt;pre&gt;Object.prototype.woof = function() {
    console.log(&amp;#x27;woof&amp;#x27;);
}&lt;/pre&gt;
  &lt;p&gt;И создать несколько своих объектов, то из каждого у них в свойстве &lt;code&gt;__proto__&lt;/code&gt; добавится метод &lt;code&gt;woof&lt;/code&gt;. Т.е. написав этот метод один раз в базовом классе &lt;code&gt;Object&lt;/code&gt; – мы можем использовать его в неограниченном количестве объектов созданных нами. &lt;/p&gt;
  &lt;h3&gt;Object.create&lt;/h3&gt;
  &lt;p&gt;У базового класса &lt;code&gt;Object&lt;/code&gt; существует метод &lt;code&gt;create&lt;/code&gt;. Он напрямую связан с прототипами, поэтому я решил рассказать и о нем.&lt;/p&gt;
  &lt;p&gt;Для того чтобы объяснить как работает этот метод и что он делает, создадим 2 объекта.&lt;/p&gt;
  &lt;p&gt;Первый объект будет представлять из себя основу для второго объекта. Называться он будет &lt;code&gt;employee&lt;/code&gt;, что в переводе означает &amp;quot;работник&amp;quot;. &lt;/p&gt;
  &lt;pre&gt;const employee = {
   name: &amp;#x27;Работник&amp;#x27;,
   position: &amp;#x27;Повар&amp;#x27;
};

console.log(employee);&lt;/pre&gt;
  &lt;p&gt;Вывод в консоль нам даст:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/82/36/8236b58b-9d65-451e-8603-a11bcc45099b.png&quot; width=&quot;644&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Для создания второго объекта нам понадобится метод &lt;code&gt;create&lt;/code&gt; из класса &lt;code&gt;Object&lt;/code&gt;:&lt;/p&gt;
  &lt;pre&gt;const manager = Object.create(employee);&lt;/pre&gt;
  &lt;p&gt;Что мы только что сделали? Мы создали новый объект, который должен описывать работника, который является менеджером.&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;Object.create(employee)&lt;/code&gt; говорит о том, что нужно создать новый объект, прототипом которого будет являться объект &lt;code&gt;employee&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;Давай выведем наш объект в консоль: &lt;/p&gt;
  &lt;pre&gt;console.log(manager);&lt;/pre&gt;
  &lt;p&gt;Результат:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/e2/eb/e2eb5f7e-3ac3-4fca-919e-7e30a72d2140.png&quot; width=&quot;346&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Объект пустой. И это неудивительно, мы же не задали ему ни одного свойства и метода. Но, что же у него теперь находится в свойстве &lt;code&gt;__proto__&lt;/code&gt;? Смотрим:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/6c/8e/6c8e2a31-9d1e-4700-8e80-33ef89f9170a.png&quot; width=&quot;386&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;А внутри него лежит объект &lt;code&gt;employee&lt;/code&gt;, как мы и заказывали. И как видишь, у этого объекта, тоже есть свое свойство &lt;code&gt;__proto__&lt;/code&gt;:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/43/c6/43c6b2d3-ff07-4bbc-8a83-e4a915946f4c.png&quot; width=&quot;752&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;И как ты заметил это класс &lt;code&gt;Object&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;У нас получилась цепочка:&lt;/p&gt;
  &lt;ol&gt;
    &lt;li&gt;Создав объект &lt;code&gt;employee&lt;/code&gt; обычным способом, мы получили объект, прототипом которого является базовый класс &lt;code&gt;Object&lt;/code&gt;.&lt;/li&gt;
    &lt;li&gt;Мы создали объект &lt;code&gt;manager&lt;/code&gt; с помощью &lt;code&gt;Object.create(employee)&lt;/code&gt;, прототипом которого указали объект &lt;code&gt;employee&lt;/code&gt;.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p&gt;Теперь, имея объект &lt;code&gt;manager&lt;/code&gt;, давай установим для него имя и должность:&lt;/p&gt;
  &lt;pre&gt;manager.name = &amp;#x27;Сергей&amp;#x27;;
manager.position = &amp;#x27;Менеджер&amp;#x27;;&lt;/pre&gt;
  &lt;p&gt;Теперь еще раз посмотрим на наш объект:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/04/f8/04f8aa0f-c1e6-4b47-9f92-d2234753fb9a.png&quot; width=&quot;628&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;У нашего объекта появились свои свойства &lt;code&gt;name&lt;/code&gt; и &lt;code&gt;position&lt;/code&gt;, при этом одноименные свойства в прототипе (&lt;code&gt;employee&lt;/code&gt;) никак не изменились.&lt;/p&gt;
  &lt;p&gt;В целом это все что нужно знать о прототипах. &lt;/p&gt;
  &lt;p&gt;Если подитожить, то получается, что прототип – это базовый объект другого объекта. Этот базовый объект присутствует у других объектов и каким-то образом &amp;quot;расширяет&amp;quot; их возможности.&lt;/p&gt;
  &lt;h2&gt;Кругом обман&lt;/h2&gt;
  &lt;p&gt;На самом деле, все предыдущие материалы о типах данных в JS были немного прикрыты страшной тайной. На самом деле в JS – нет строкового типа, числового, логического и т.д. В JS – всё объекты.&lt;/p&gt;
  &lt;p&gt;Это достаточно просто понять. К примеру, создадим обычную строку:&lt;/p&gt;
  &lt;pre&gt;const str = &amp;#x27;строка&amp;#x27;;&lt;/pre&gt;
  &lt;p&gt;Несмотря на то, что это обычная строка – у нее есть методы. К примеру:&lt;/p&gt;
  &lt;pre&gt;console.log(str.toUpperCase()); //выведет: &amp;quot;СТРОКА&amp;quot;&lt;/pre&gt;
  &lt;p&gt;Мы не определяли этот метод, но он существует. Он переводит всю строку к верхнему регистру.&lt;/p&gt;
  &lt;p&gt;Это происходит потому, что строковый тип, это на самом деле тоже объект, а именно, объект &lt;code&gt;String&lt;/code&gt;. Который в свою очередь основан на объекте &lt;code&gt;Object&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;Получается, что фактически написав такую вот конструкцию:&lt;/p&gt;
  &lt;pre&gt;const str = &amp;#x27;строка&amp;#x27;;&lt;/pre&gt;
  &lt;p&gt;Для JS это тоже самое что и:&lt;/p&gt;
  &lt;pre&gt;const str = new String(&amp;#x27;строка&amp;#x27;);&lt;/pre&gt;
  &lt;p&gt;Строка &lt;code&gt;str&lt;/code&gt; на самом деле является объектом класса &lt;code&gt;String&lt;/code&gt;, а прототипом объекта класса &lt;code&gt;String&lt;/code&gt; является объект класса &lt;code&gt;Object&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;Все в JS создается на основе класса &lt;code&gt;Object&lt;/code&gt;. Он главный, он батька.&lt;/p&gt;

</content></entry><entry><id>java-script-stupid:KNNOyrWSY</id><link rel="alternate" type="text/html" href="https://teletype.in/@java-script-stupid/KNNOyrWSY?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=java-script-stupid"></link><title>Замыкания</title><published>2020-05-07T19:07:36.274Z</published><updated>2020-05-08T08:30:13.323Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://teletype.in/files/bd/6f/bd6f10bf-7daa-444f-bfed-5a4656d57455.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://teletype.in/files/d5/2b/d52b57e9-6e40-478f-bf89-3432e852ced6.png&quot;&gt;Сегодня речь пойдет о замыканиях в JavaScript. Для многих эта тема подсознательно воспринимается непонятной и от того сложной. Но, в действительности, в замыканиях нет ничего страшного и сложного.</summary><content type="html">
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/d5/2b/d52b57e9-6e40-478f-bf89-3432e852ced6.png&quot; width=&quot;1920&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Сегодня речь пойдет о замыканиях в JavaScript. Для многих эта тема подсознательно воспринимается непонятной и от того сложной. Но, в действительности, в замыканиях нет ничего страшного и сложного.&lt;/p&gt;
  &lt;p&gt;Что же такое замыкание? Если говорить простыми словами, то это просто функция в функции. Вот и все. Да-да. Так вот просто. Это функция, которая находится внутри другой функции.&lt;/p&gt;
  &lt;p&gt;Начнем сразу же с примеров, т.к. на них будет разобраться намного проще. &lt;/p&gt;
  &lt;pre&gt;function hi() {
    return function() {
        console.log(&amp;#x27;Привет&amp;#x27;);
    }
}&lt;/pre&gt;
  &lt;p&gt;Такая вот незамысловатая конструкция: у нас имеется функция &lt;code&gt;hi&lt;/code&gt;, которая возвращает другую функцию.&lt;/p&gt;
  &lt;p&gt;Получается, что если вызвать функцию &lt;code&gt;hi&lt;/code&gt;, то может показаться, что ничего не произошло, так как в консоль не будет выведено слово &lt;code&gt;Привет&lt;/code&gt;:&lt;/p&gt;
  &lt;pre&gt;hi(); // в консоль ничего не выведется&lt;/pre&gt;
  &lt;p&gt;Так как функция hi возвращает новую функцию, то нам нужно ее вызвать, перед эти, для наглядности запишем ее в константу и вызовем ее:&lt;/p&gt;
  &lt;pre&gt;const sayHi = hi();

sayHi(); // выведет в консоль слово &amp;quot;Привет&amp;quot;&lt;/pre&gt;
  &lt;p&gt;Только после этой манипуляции мы сможем визуально увидеть результат. &lt;/p&gt;
  &lt;p&gt;Итак, первым шагом мы разобрались, что функция &lt;code&gt;hi&lt;/code&gt; в результате своего выполнения возвращает новую функцию. Но пока что совсем непонятно зачем это нужно. &lt;/p&gt;
  &lt;p&gt;Давай разбираться зачем это нужно. &lt;/p&gt;
  &lt;p&gt;В нашу функцию &lt;code&gt;hi&lt;/code&gt; добавим параметр(аргумент), в который будем записывать имя человека, а в функции, которая сейчас выводит нам слово Привет в консоль добавим это имя. В итоге получим такой код:&lt;/p&gt;
  &lt;pre&gt;function hi(name) {
    return function() {
        console.log(&amp;#x60;Привет, ${name}&amp;#x60;);
    }
}&lt;/pre&gt;
  &lt;p&gt;Теперь заставим все это работать:&lt;/p&gt;
  &lt;pre&gt;const sayHi = hi(&amp;#x27;Вася&amp;#x27;);
sayHi(); // выведет в консоль: Привет, Вася&lt;/pre&gt;
  &lt;p&gt;Стоит заметить, что имя мы передавали только в функцию &lt;code&gt;hi&lt;/code&gt;, однако, та функция, которую возвращает функция &lt;code&gt;hi&lt;/code&gt; так же имеет доступ к этому имени и спокойно может его использовать. На самом деле это и есть замыкание. Возвращаемая функция замыкает в себе значение переменной &lt;code&gt;name&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;Поправим немного код, для большего понимания:&lt;/p&gt;
  &lt;pre&gt;const sayHiVasya = hi(&amp;#x27;Вася&amp;#x27;);
const sayHiPetya = hi(&amp;#x27;Петя&amp;#x27;);
sayHiVasya(); // выведет в консоль: Привет, Вася
sayHiPetya(); // выведет в консоль: Привет, Петя&lt;/pre&gt;
  &lt;p&gt;Как видишь, мы передаем имена только в нашу функцию &lt;code&gt;hi&lt;/code&gt;, и эти имена замыкаются в возвращаемых функциях. &lt;/p&gt;
  &lt;h2&gt;Создание ссылок для соц. сетей&lt;/h2&gt;
  &lt;p&gt;Может быть еще не совсем понятно, поэтому давай сделаем более близкий к практике пример использующий замыкания.&lt;/p&gt;
  &lt;p&gt;Давай сделаем с тобой некий генератор ссылок для социальных сетей.&lt;/p&gt;
  &lt;pre&gt;function createSocLink(socialNetwork) {
    return function(nickname) {
        return &amp;#x60;https://${socialNetwork}/${nickname}&amp;#x60;;
    }
}&lt;/pre&gt;
  &lt;p&gt;Итак, сначала разберем все в этом генераторе, а потом разберемся как им пользоваться. &lt;/p&gt;
  &lt;p&gt;В функцию &lt;code&gt;createSocLink&lt;/code&gt; мы передаем параметр &lt;code&gt;socialNetwork&lt;/code&gt;, который должен представлять из себя ссылку на какую-либо социальную сеть, т.е. должен иметь вид, к примеру:&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;vk.com&lt;/li&gt;
    &lt;li&gt;instagram.com&lt;/li&gt;
    &lt;li&gt;facebook.com&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;Эта функция возвращает нам другую функцию, которая тоже ждет параметра, который указывает на никнейм пользователя в указанной социальной сети. Т.е. когда мы будем вызывать ту функцию, которую нам вернет функция createSocLink мы должны будем передать в нее параметр с указанием никнейма. Как выглядит никнейм в социальных сетях, думаю у тебя вопросов не вызовет.&lt;/p&gt;
  &lt;p&gt;Итак, пробуем все это запустить. &lt;/p&gt;
  &lt;p&gt;Так как функция &lt;code&gt;createSocLink&lt;/code&gt; вернет нам новую функцию, то запишем ее в константу:&lt;/p&gt;
  &lt;pre&gt;const createVkLink = createSocLink(&amp;#x27;vk.com&amp;#x27;);&lt;/pre&gt;
  &lt;p&gt;Теперь в &lt;code&gt;createVkLink&lt;/code&gt; у нас лежит функция, которая умеет делать ссылки для социальной сети Вконтакте. Теперь вызовем эту функцию и не забудем передать в нее аргумент, который должен указывать на никнейм пользователя:&lt;/p&gt;
  &lt;pre&gt;const createVkLink = createSocLink(&amp;#x27;vk.com&amp;#x27;);

console.log(createVkLink(&amp;#x27;durov&amp;#x27;));
// в консоль выведется: https://vk.com/durov&lt;/pre&gt;
  &lt;p&gt;Как видишь, мы создали ссылку на страницу создателя Вконтакте Павла Дурова.&lt;/p&gt;
  &lt;p&gt;Теперь давай создадим ссылки с помощью генератора на другие соц. сети и ты увидишь, в чем прелесть замыканий:&lt;/p&gt;
  &lt;pre&gt;const createVkLink = createSocLink(&amp;#x27;vk.com&amp;#x27;);
const createInstagramLink = createSocLink(&amp;#x27;instagram.com&amp;#x27;);
const createFacebookLink = createSocLink(&amp;#x27;facebook.com&amp;#x27;);&lt;/pre&gt;
  &lt;p&gt;Мы получили 3 новых функции:&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;&lt;code&gt;createVkLink&lt;/code&gt; – создаем ссылки на страницы пользователей в Вконтакте;&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;createInstagramLink&lt;/code&gt; – создает ссылки на страницы пользователей в Instagram; &lt;/li&gt;
    &lt;li&gt;&lt;code&gt;createFacebookLink&lt;/code&gt; – создает ссылки на страницы пользователей в Facebook.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;Попробуем их в работе:&lt;/p&gt;
  &lt;pre&gt;console.log(createVkLink(&amp;#x27;durov&amp;#x27;));
console.log(createVkLink(&amp;#x27;admin&amp;#x27;));
console.log(createVkLink(&amp;#x27;vasya&amp;#x27;));
console.log(&amp;#x27;*****&amp;#x27;);
console.log(createInstagramLink(&amp;#x27;durov&amp;#x27;));
console.log(createInstagramLink(&amp;#x27;admin&amp;#x27;));
console.log(createInstagramLink(&amp;#x27;vasya&amp;#x27;));
console.log(&amp;#x27;*****&amp;#x27;);
console.log(createFacebookLink(&amp;#x27;durov&amp;#x27;));
console.log(createFacebookLink(&amp;#x27;admin&amp;#x27;));
console.log(createFacebookLink(&amp;#x27;vasya&amp;#x27;));&lt;/pre&gt;
  &lt;p&gt;Получаем результат:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/59/8b/598b1d25-ae02-498e-b76d-41d81ce62cc5.png&quot; width=&quot;1034&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Ссылки прекрасно сгенерировались. Благодаря замыканию, мы получили список из 3ех генераторов ссылок:&lt;/p&gt;
  &lt;pre&gt;const createVkLink = createSocLink(&amp;#x27;vk.com&amp;#x27;);
const createInstagramLink = createSocLink(&amp;#x27;instagram.com&amp;#x27;);
const createFacebookLink = createSocLink(&amp;#x27;facebook.com&amp;#x27;);&lt;/pre&gt;
  &lt;p&gt;И каждый генератор теперь может генерировать сколько угодно ссылок, при этом, в него нужно передавать только никнейм пользователя, а сам адрес социальной сети будет браться из замыкания.&lt;/p&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;h2&gt;Домашнее задание&lt;/h2&gt;
  &lt;p&gt;Создать функцию &lt;code&gt;calc&lt;/code&gt; используя замыкания, которую можно использовать так:&lt;/p&gt;
  &lt;pre&gt;const plus = calc(10);
plus(5); // должно вывести значение 15
plus(45); // должно вывести значение 55&lt;/pre&gt;

</content></entry><entry><id>java-script-stupid:ZYjyvsU9f</id><link rel="alternate" type="text/html" href="https://teletype.in/@java-script-stupid/ZYjyvsU9f?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=java-script-stupid"></link><title>this, call, apply, bind</title><published>2020-05-03T09:34:05.713Z</published><updated>2020-05-03T09:52:04.257Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://teletype.in/files/97/71/97712f26-b6cb-454c-a5fa-73f1b9293ccb.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://teletype.in/files/84/58/8458f706-6711-4671-8d9a-2b1d1fff87e6.png&quot;&gt;Сегодня хотелось бы рассказать о таких надуманно сложных вещах как call, bind, apply, ну и, соответственно, затронуть this. Все эти слова связаны одним словом – контекст. Но, обо всем по-порядку.</summary><content type="html">
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/84/58/8458f706-6711-4671-8d9a-2b1d1fff87e6.png&quot; width=&quot;1920&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Сегодня хотелось бы рассказать о таких надуманно сложных вещах как &lt;code&gt;call&lt;/code&gt;, &lt;code&gt;bind&lt;/code&gt;, &lt;code&gt;apply&lt;/code&gt;, ну и, соответственно, затронуть &lt;code&gt;this&lt;/code&gt;. Все эти слова связаны одним словом – контекст. Но, обо всем по-порядку.&lt;/p&gt;
  &lt;p&gt;Многие боятся даже подходить к этой теме потому что им кажется, что это что-то невероятно сложное и непонятное. Поэтому, надеюсь, что сегодня я развенчаю все ваши страхи и непонятки по этой теме.&lt;/p&gt;
  &lt;p&gt;Все примеры будут сделаны на основе функций, поэтому нужно представлять как работают функции.&lt;/p&gt;
  &lt;p&gt;Статьи о функциях: &lt;a href=&quot;https://teletype.in/@java-script-stupid/SJ_9z4R6B&quot; target=&quot;_blank&quot;&gt;Функции&lt;/a&gt;, &lt;a href=&quot;https://teletype.in/@java-script-stupid/r1pKooU0H&quot; target=&quot;_blank&quot;&gt;Функции. Возврат значения&lt;/a&gt;&lt;/p&gt;
  &lt;h2&gt;Ключевое слово this&lt;/h2&gt;
  &lt;p&gt;Создадим обычную функцию и сразу же вызовем ее:&lt;/p&gt;
  &lt;pre&gt;function hi() {
    console.log(&amp;#x27;Привет&amp;#x27;, this);
}

hi();&lt;/pre&gt;
  &lt;p&gt;Функция выводит в консоль слово &lt;code&gt;Привет&lt;/code&gt; и &lt;code&gt;this&lt;/code&gt;. Если заглянуть в консоль, то увидим следующее:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/3f/a6/3fa67ec3-9aa4-4681-9af2-dd6e140d3db1.png&quot; width=&quot;932&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Если со словом &lt;code&gt;Привет&lt;/code&gt; все понятно, то вот что это такое вывелось на месте &lt;code&gt;this&lt;/code&gt;? Почему вывелся какой-то объект &lt;code&gt;Window&lt;/code&gt;?&lt;/p&gt;
  &lt;p&gt;Когда мы создаем глобальные объекты, то они автоматически начинают принадлежать глобальному объекту &lt;code&gt;window&lt;/code&gt; – самому главному объекту в браузере.&lt;/p&gt;
  &lt;p&gt;На самом деле все методы, которые ты часто вызываешь, например: &lt;code&gt;console.log()&lt;/code&gt;, &lt;code&gt;alert&lt;/code&gt;, &lt;code&gt;prompt&lt;/code&gt; и т.д. находятся внутри объекта &lt;code&gt;window&lt;/code&gt; и являются его методами. &lt;/p&gt;
  &lt;p&gt;Это достаточно просто проверить. Просто попробуй вызвать эти методы так:&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;&lt;code&gt;window.console.log(&amp;#x27;Привет&amp;#x27;);&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;window.alert(&amp;#x27;Привет&amp;#x27;);&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;window.prompt(&amp;#x27;Как тебя зовут?&amp;#x27;);&lt;/code&gt;&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;Надеюсь ты попробовал это и понял, что абсолютно ничего не изменилось. А теперь, вернемся к нашей функции:&lt;/p&gt;
  &lt;pre&gt;function hi() {
    console.log(&amp;#x27;Привет&amp;#x27;, this);
}

hi();&lt;/pre&gt;
  &lt;p&gt;На самом деле, когда мы вызываем функцию, то мы вызываем ее так же из объекта window, т.е. вызов нашей функции можно переписать так:&lt;/p&gt;
  &lt;pre&gt;window.hi();&lt;/pre&gt;
  &lt;p&gt;Из всего выше сказанного можно сделать вывод, что наша функция запускается из объекта &lt;code&gt;window&lt;/code&gt;, т.е. контекст, в котором выполняется наша функция так же равен объекту &lt;code&gt;window&lt;/code&gt;. А ключевое слово &lt;code&gt;this&lt;/code&gt; как раз и содержит внутри себя контекст, в котором вызывается функция/метод.&lt;/p&gt;
  &lt;p&gt;А теперь создадим объект:&lt;/p&gt;
  &lt;pre&gt;const man = {
   name: &amp;#x27;Вася&amp;#x27;,
   lastName: &amp;#x27;Пупкин&amp;#x27;,
   age: 30,
   sayHi: hi
};&lt;/pre&gt;
  &lt;p&gt;Простой объект описывающий абстрактного мужчину. Обрати внимание на метод &lt;code&gt;sayHi&lt;/code&gt;. В него мы передали ссылку на функцию, которую создали в самом начале.&lt;/p&gt;
  &lt;p&gt;Давай вызовем метода &lt;code&gt;sayHi&lt;/code&gt; из нашего объекта:&lt;/p&gt;
  &lt;pre&gt;man.sayHi();&lt;/pre&gt;
  &lt;p&gt;А теперь посмотрим в консоль, что же теперь вывелось на месте &lt;code&gt;this&lt;/code&gt;. Получаем следующий результат:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/97/75/97758a5c-de07-4010-bc09-0646d7f2f5c6.png&quot; width=&quot;932&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;В этом случае, значение  &lt;code&gt;this&lt;/code&gt; (контекста) становится равным самому объекту.  Почему так случилось? Все очень просто. &lt;/p&gt;
  &lt;p&gt;Первый раз мы вызывали функцию &lt;code&gt;hi&lt;/code&gt; и значение &lt;code&gt;this&lt;/code&gt;, внутри нее было равно объекту &lt;code&gt;Window&lt;/code&gt;, потому что мы запускали функцию в контексте объекта &lt;code&gt;Window&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;А сейчас, мы создали свой объект, и запустили функцию &lt;code&gt;hi&lt;/code&gt; из него. Получается, что место вызова функции изменилось с объекта &lt;code&gt;Window&lt;/code&gt; на объект &lt;code&gt;man&lt;/code&gt;. Следственно, изменилось и значение this с &lt;code&gt;Window&lt;/code&gt; на &lt;code&gt;man&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;Теперь коротко:&lt;/strong&gt; &lt;em&gt;значение this равно тому&lt;/em&gt; объекту в контексте которого было вызвано.&lt;/p&gt;
  &lt;p&gt;С контекстом разобрались, давай разбираться с этими страшными методами: &lt;code&gt;call&lt;/code&gt;, &lt;code&gt;apply&lt;/code&gt;, &lt;code&gt;bind&lt;/code&gt;.&lt;/p&gt;
  &lt;h2&gt;Метод bind&lt;/h2&gt;
  &lt;p&gt;Мы ранее создали объект &lt;code&gt;man&lt;/code&gt;, а теперь еще создадим объект &lt;code&gt;woman&lt;/code&gt;.  Итого, получим:&lt;/p&gt;
  &lt;pre&gt;const man = {
   name: &amp;#x27;Вася&amp;#x27;,
   lastName: &amp;#x27;Пупкин&amp;#x27;,
   age: 30,
   sayHi: hi
};

const woman = {
   name: &amp;#x27;Катя&amp;#x27;,
   lastName: &amp;#x27;Иванова&amp;#x27;,
   age: 25
};&lt;/pre&gt;
  &lt;p&gt;Итак, мы имеем 2 объекта, один из которых описывает мужчину, а второй женщину.&lt;/p&gt;
  &lt;p&gt;Для примера, создадим еще один объект (логгер), которому добавим один метод:&lt;/p&gt;
  &lt;pre&gt;const Logger = {
   info: function() {
       console.log(&amp;#x27;Имя: &amp;#x27;, this.name);
       console.log(&amp;#x27;Фамилия: &amp;#x27;, this.lastName);
       console.log(&amp;#x27;Возраст: &amp;#x27;, this.age);
   }
};&lt;/pre&gt;
  &lt;p&gt;Внутри объекта &lt;code&gt;Logger&lt;/code&gt; мы создали метод &lt;code&gt;info&lt;/code&gt;, который должен выводить информацию о наших объектах. Мы использовали ключевое слово &lt;code&gt;this&lt;/code&gt; внутри этого метода:&lt;/p&gt;
  &lt;pre&gt;console.log(&amp;#x27;Имя: &amp;#x27;, this.name);
console.log(&amp;#x27;Фамилия: &amp;#x27;, this.lastName);
console.log(&amp;#x27;Возраст: &amp;#x27;, this.age);&lt;/pre&gt;
  &lt;p&gt;Но что будет, если вызвать этот метод прямо сейчас?&lt;/p&gt;
  &lt;pre&gt;Logger.info();&lt;/pre&gt;
  &lt;p&gt;Результат:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/7d/5d/7d5da565-4ccd-4e66-b48c-dbeeb9cc9162.png&quot; width=&quot;932&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Мы получили &lt;code&gt;undefined&lt;/code&gt; во всех случаях и это более чем логично. Т.к. мы обращаемся к ключевому слову &lt;code&gt;this&lt;/code&gt; внутри метода &lt;code&gt;info&lt;/code&gt;, который принадлежит объекту &lt;code&gt;Logger&lt;/code&gt;, то и контекст, т.е. само ключевое &lt;code&gt;this&lt;/code&gt; имеет значение, которое равно объекту &lt;code&gt;Logger&lt;/code&gt;. А внутри этого объекта у нас имеется только один метод info. Никаких свойств с именами &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;lastName&lt;/code&gt;, &lt;code&gt;age&lt;/code&gt; у нас нет.&lt;/p&gt;
  &lt;p&gt;Как сделать так, чтобы с помощью объекта &lt;code&gt;Logger&lt;/code&gt; и его метода &lt;code&gt;info&lt;/code&gt; вывести данные, например, об объекте &lt;code&gt;man&lt;/code&gt;?&lt;/p&gt;
  &lt;p&gt;Как раз тут на помощь и приходит тот самый страшный метод &lt;code&gt;bind&lt;/code&gt;:&lt;/p&gt;
  &lt;pre&gt;const loggerMan = Logger.info.bind(man);&lt;/pre&gt;
  &lt;p&gt;У каждой функции в JS существует метод &lt;code&gt;bind&lt;/code&gt;, благодаря которому мы можем любой функции задать контекст, внутри которого она должна будет выполняться.&lt;/p&gt;
  &lt;p&gt;Метод &lt;code&gt;bind&lt;/code&gt; возвращает новую функцию, к которой будет привязан тот контекст, который мы указали как аргумент метода &lt;code&gt;bind&lt;/code&gt;. В нашем случае контекстом мы указали объект &lt;code&gt;man&lt;/code&gt;.  Так как &lt;code&gt;bind&lt;/code&gt;  возвращает новую функцию, то мы ее запишем в константу &lt;code&gt;loggerMan&lt;/code&gt;. &lt;/p&gt;
  &lt;p&gt;Теперь вызовем полученную функцию:&lt;/p&gt;
  &lt;pre&gt;loggerMan();&lt;/pre&gt;
  &lt;p&gt;Результат:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/f7/b2/f7b23b45-ce09-4f70-948a-77fee522f7e9.png&quot; width=&quot;924&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Как видишь, &lt;code&gt;bind&lt;/code&gt; успешно привязал в качестве контекста объект &lt;code&gt;man&lt;/code&gt; и информация о нем успешно вывелась в консоль.  &lt;/p&gt;
  &lt;p&gt;Теперь мы хотим получить информацию об объекте &lt;code&gt;woman&lt;/code&gt; с помощью нашего логгера. Для этого делаем тоже самое:&lt;/p&gt;
  &lt;pre&gt;const loggerWoman = Logger.info.bind(woman);&lt;/pre&gt;
  &lt;p&gt;С помощью bind мы привязываем новый контекст для метода info со значением woman.&lt;/p&gt;
  &lt;p&gt;Вызовем:&lt;/p&gt;
  &lt;pre&gt;loggerWoman();&lt;/pre&gt;
  &lt;p&gt;Результат:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/f0/be/f0be6b29-ffe2-430f-8d51-15182d094da4.png&quot; width=&quot;922&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Вуаля, все так же прекрасно работает. И ведь совсем не сложно и не страшно не так ли?&lt;/p&gt;
  &lt;p&gt;И последнее, что хотелось бы тут сказать. В функцию инфо мы можем дополнительно передавать какие-либо параметры, если это нужно. Давай немного исправим метод &lt;code&gt;info&lt;/code&gt; в объекте &lt;code&gt;Logger&lt;/code&gt;. Пускай он будет принимать пол человека:&lt;/p&gt;
  &lt;pre&gt;const Logger = {
   info: function(sex) {
       console.log(&amp;#x27;Имя: &amp;#x27;, this.name);
       console.log(&amp;#x27;Фамилия: &amp;#x27;, this.lastName);
       console.log(&amp;#x27;Возраст: &amp;#x27;, this.age);
       console.log(&amp;#x27;Пол: &amp;#x27;, sex);
   }
};&lt;/pre&gt;
  &lt;p&gt;Все что мы сделали – это добавили в определение функции параметр &lt;code&gt;sex&lt;/code&gt; и выводим его под всеми остальными данными. Остается вопрос, как нам туда это все передать, если нам еще и контекст нужно сменить. Все очень просто. У нас уже есть полученные функции для наших объектов:&lt;/p&gt;
  &lt;pre&gt;const loggerMan = Logger.info.bind(man);
const loggerWoman = Logger.info.bind(woman);&lt;/pre&gt;
  &lt;p&gt;Чтобы передать параметр sex, нам достаточно указать его аргументом наших функций при их вызове:&lt;/p&gt;
  &lt;pre&gt;loggerMan(&amp;#x27;мужской&amp;#x27;);
loggerWoman(&amp;#x27;женский&amp;#x27;);&lt;/pre&gt;
  &lt;p&gt;Смотрим на результат:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/54/a0/54a0ba8e-0ea5-4ed7-a6aa-a9cdde06a889.png&quot; width=&quot;892&quot; /&gt;
  &lt;/figure&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/15/d7/15d78836-28f5-4454-a2f3-9380f0aeb016.png&quot; width=&quot;898&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Все прекрасно отработало. Но это не единственный способ передачи параметров.&lt;/p&gt;
  &lt;p&gt;Есть еще один способ передачи параметров – указать их при вызове метода &lt;code&gt;bind&lt;/code&gt;. &lt;/p&gt;
  &lt;p&gt;Получим следующее:&lt;/p&gt;
  &lt;pre&gt;const loggerMan = Logger.info.bind(man, &amp;#x27;мужской&amp;#x27;);
const loggerWoman = Logger.info.bind(woman, &amp;#x27;женский&amp;#x27;);

loggerMan();
loggerWoman();&lt;/pre&gt;
  &lt;p&gt;Результат:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/09/bf/09bfc854-4775-4c21-9d99-c3a7eaf81a61.png&quot; width=&quot;876&quot; /&gt;
  &lt;/figure&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/39/1d/391d25dc-48ff-4429-8550-d538ceeb20a9.png&quot; width=&quot;892&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Результат никак не поменялся и все прекрасно продолжает работать.&lt;/p&gt;
  &lt;p&gt;Первый аргумент в методе &lt;code&gt;bind&lt;/code&gt; – это сам контекст, который нужно привязать к функции. А вот дальше, через запятую, можно передавать сколько угодно дополнительных параметров(аргументов), которые должны попасть в метод &lt;code&gt;info&lt;/code&gt;. В нашем случае нам нужно было передать только один аргумент &lt;code&gt;sex&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;На этом с &lt;code&gt;bind&lt;/code&gt; все. Не такой и страшный зверь, как мог бы показаться.&lt;/p&gt;
  &lt;h2&gt;Метод call&lt;/h2&gt;
  &lt;p&gt;Что же, продолжим убивать страх внутри тебя. Теперь на очереди метод &lt;code&gt;call&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;Ты не поверишь, но он делает то же самое, что и &lt;code&gt;bind&lt;/code&gt;. С одной маленькой поправкой: если метод &lt;code&gt;bind&lt;/code&gt; привязывает контекст и  возвращает новую функцию с этим контекстом, то метод &lt;code&gt;call&lt;/code&gt; привязывая контекст, сразу же вызывает указанную функцию, а не возвращает новую.&lt;/p&gt;
  &lt;p&gt;Продублирую наш код:&lt;/p&gt;
  &lt;pre&gt;const Logger = {
   info: function(sex) {
       console.log(&amp;#x27;Имя: &amp;#x27;, this.name);
       console.log(&amp;#x27;Фамилия: &amp;#x27;, this.lastName);
       console.log(&amp;#x27;Возраст: &amp;#x27;, this.age);
       console.log(&amp;#x27;Пол: &amp;#x27;, sex);
   }
};

const man = {
   name: &amp;#x27;Вася&amp;#x27;,
   lastName: &amp;#x27;Пупкин&amp;#x27;,
   age: 30,
   sayHi: hi
};

const woman = {
   name: &amp;#x27;Катя&amp;#x27;,
   lastName: &amp;#x27;Иванова&amp;#x27;,
   age: 25
};

const loggerMan = Logger.info.bind(man, &amp;#x27;мужской&amp;#x27;);
const loggerWoman = Logger.info.bind(woman, &amp;#x27;женский&amp;#x27;);

loggerMan();
loggerWoman();&lt;/pre&gt;
  &lt;p&gt;Итак, давай привяжем контекст с помощью &lt;code&gt;call&lt;/code&gt;, а не &lt;code&gt;bind&lt;/code&gt; и посмотрим в чем же разница.&lt;/p&gt;
  &lt;p&gt;Было:&lt;/p&gt;
  &lt;pre&gt;const loggerMan = Logger.info.bind(man, &amp;#x27;мужской&amp;#x27;);
const loggerWoman = Logger.info.bind(woman, &amp;#x27;женский&amp;#x27;);&lt;/pre&gt;
  &lt;p&gt;Стало:&lt;/p&gt;
  &lt;pre&gt;Logger.info.call(man, &amp;#x27;мужской&amp;#x27;);
Logger.info.call(woman, &amp;#x27;женский&amp;#x27;);&lt;/pre&gt;
  &lt;p&gt;Так как метод &lt;code&gt;call&lt;/code&gt; после привязки контекста сразу же выполняет функцию (&lt;code&gt;info&lt;/code&gt;), и наша функция ничего не возвращает (внутри нет ключевого слова &lt;code&gt;return&lt;/code&gt;), то не имеет никакого смысла записывать результат данной функции, так как он всегда в нашем случае будет равен &lt;code&gt;undefined&lt;/code&gt;, поэтому создание констант &lt;code&gt;loggerMan&lt;/code&gt; и &lt;code&gt;loggerWoman&lt;/code&gt; делать не нужно.&lt;/p&gt;
  &lt;p&gt;И вот так вот просто. &lt;code&gt;call&lt;/code&gt; – ничуть не страшнее &lt;code&gt;bind&lt;/code&gt;. Вся разница:&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;&lt;code&gt;bind&lt;/code&gt; привязывает контекст и возвращает новую функцию и мы можем вызвать ее в любом месте;&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;call&lt;/code&gt; привязывает контекст и сразу же вызывает функцию&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;Собственно, больше о &lt;code&gt;call&lt;/code&gt; и сказать нечего.&lt;/p&gt;
  &lt;h2&gt;Метод apply&lt;/h2&gt;
  &lt;p&gt;По всему повествованию статьи, ты мог заметить, что о методе &lt;code&gt;bind&lt;/code&gt; было сказано очень много. О методе &lt;code&gt;call&lt;/code&gt; – уже куда меньше, потому что это одно и тоже с одним исключением. Будешь смеяться, но метод &lt;code&gt;apply&lt;/code&gt; – это тоже самое, что и &lt;code&gt;call&lt;/code&gt;. И существует только одно отличие.&lt;/p&gt;
  &lt;p&gt;Если метод call (как, собственно, и &lt;code&gt;bind&lt;/code&gt;) первым аргументом принимает контекст, а дальше через запятую принимает аргументы для функции (получается, что аргументов может быть разное количество), то метод &lt;code&gt;apply&lt;/code&gt; принимает всего 2 аргумента:&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;контекст (так же как &lt;code&gt;bind&lt;/code&gt; и &lt;code&gt;call&lt;/code&gt;);&lt;/li&gt;
    &lt;li&gt;массив параметров.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;Т.е. если в &lt;code&gt;bind&lt;/code&gt; и &lt;code&gt;call&lt;/code&gt; мы можем передавать параметры функции через запятую, то в &lt;code&gt;apply&lt;/code&gt; мы должны передать их в массиве. И в этом вся разница. Давай перепишем код с &lt;code&gt;call&lt;/code&gt; на &lt;code&gt;apply&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;Было:&lt;/p&gt;
  &lt;pre&gt;Logger.info.call(man, &amp;#x27;мужской&amp;#x27;);
Logger.info.call(woman, &amp;#x27;женский&amp;#x27;);&lt;/pre&gt;
  &lt;p&gt;Стало:&lt;/p&gt;
  &lt;pre&gt;Logger.info.apply(man, [&amp;#x27;мужской&amp;#x27;]);
Logger.info.apply(woman, [&amp;#x27;женский&amp;#x27;]);&lt;/pre&gt;
  &lt;p&gt;Вот и вся разница. В случае с &lt;code&gt;call&lt;/code&gt; мы передали аргумент sex для функции &lt;code&gt;info&lt;/code&gt; как обычную строку. А в случае с &lt;code&gt;apply&lt;/code&gt; мы обязаны передавать все аргументы в массиве. &lt;/p&gt;
  &lt;p&gt;Вот и все. Надеюсь, ты поборол свой страх и понял, что все, что связано с контекстом и, конкретно, данными методами – совсем не страшно.&lt;/p&gt;

</content></entry><entry><id>java-script-stupid:yTEvPMH9B</id><link rel="alternate" type="text/html" href="https://teletype.in/@java-script-stupid/yTEvPMH9B?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=java-script-stupid"></link><title>Объекты. Методы</title><published>2020-04-21T21:18:15.963Z</published><updated>2020-04-21T21:19:58.783Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://teletype.in/files/2b/44/2b443aa0-111f-42e4-a637-f0afcb76ebe1.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://teletype.in/files/a2/d2/a2d2d1ff-56fb-4596-a300-6b830e4b6e4f.png&quot;&gt;Продолжаем тему объектов и сегодня на повестке дня – методы. </summary><content type="html">
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/a2/d2/a2d2d1ff-56fb-4596-a300-6b830e4b6e4f.png&quot; width=&quot;1920&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Продолжаем тему объектов и сегодня на повестке дня – методы. &lt;/p&gt;
  &lt;h2&gt;Что такое метод объекта?&lt;/h2&gt;
  &lt;p&gt;На самом деле метод – это обычная функция. Да, ничего сверхъестественного и страшного. Обычная, особо ничем не примечательная функция, которая просто напросто находится внутри объекта и как-то связана с самим этим объектом. &lt;/p&gt;
  &lt;h2&gt;Добавление метода&lt;/h2&gt;
  &lt;p&gt;В &lt;a href=&quot;https://teletype.in/@java-script-stupid/myYxVRS3K&quot; target=&quot;_blank&quot;&gt;прошлой статье&lt;/a&gt; мы рассматривали свойства объекта и создали объект котика:&lt;/p&gt;
  &lt;pre&gt;const catVasya = {
   name: &amp;#x27;Вася&amp;#x27;,
   age: 2,
   color: &amp;#x27;рыжий&amp;#x27;,
   weight: 3
};&lt;/pre&gt;
  &lt;p&gt;Так вот, мы имеем имя котика, его возраст, цвет и вес. Получается, что мы дали котику некое описание, но вот делать наш котик пока что ничего не умеет. &lt;/p&gt;
  &lt;p&gt;Чтобы он что-то научился делать нам нужно добавить в объект метод (функцию). Давай научим котика мяукать, для этого добавим в объект метод под названием &lt;code&gt;mew&lt;/code&gt;:&lt;/p&gt;
  &lt;pre&gt;const catVasya = {
   name: &amp;#x27;Вася&amp;#x27;,
   age: 2,
   color: &amp;#x27;рыжий&amp;#x27;,
   weight: 3,
   mew: function() {
      console.log(&amp;#x27;мяу-мяу&amp;#x27;);
   }
};&lt;/pre&gt;
  &lt;p&gt;Как видишь, функция в объект добавляется точно так же как и обычное свойство, за тем исключением, что значение этого свойства – функция.&lt;/p&gt;
  &lt;p&gt;Правда, хочу заметить, что это не единственный способ определить метод внутри объекта. Очень часто ты можешь увидеть такую запись:&lt;/p&gt;
  &lt;pre&gt;mew() {
  console.log(&amp;#x27;мяу-мяу&amp;#x27;);
}&lt;/pre&gt;
  &lt;p&gt;Эта запись считается краткой и используется достаточно часто. &lt;/p&gt;
  &lt;h2&gt;Вызов метода&lt;/h2&gt;
  &lt;p&gt;Теперь у получившегося объекта мы можем вызвать данный метод как обычную функцию:&lt;/p&gt;
  &lt;pre&gt;catVasya.mew();
// выведет в консоль: &amp;#x27;мяу-мяу&amp;#x27;&lt;/pre&gt;
  &lt;p&gt;В целом, все очень просто. Но, согласись, если бы на этом все заканчивалось, то особого смысла в методах и не было бы. Но, есть одна очень ценная вещь, которую умеют методы – обращаться к другим свойствам и методам того же объекта.&lt;/p&gt;
  &lt;p&gt;Давай представим, что мы попали в сказочную страну, где животные разговаривают. Следственно, наш кот, может сказать, как его зовут. Поэтому, добавим ему такую возможность добавив в наш объект метод &lt;code&gt;sayName&lt;/code&gt;. &lt;/p&gt;
  &lt;p&gt;Внутри объекта лежит свойство &lt;code&gt;name&lt;/code&gt;, следственно, из метода &lt;code&gt;sayName&lt;/code&gt; нам как-то нужно &amp;quot;достучаться&amp;quot; до этого свойства. Делается это просто, с помощью ключевого свойства &lt;code&gt;this&lt;/code&gt;:&lt;/p&gt;
  &lt;pre&gt;const catVasya = {
   name: &amp;#x27;Вася&amp;#x27;,
   age: 2,
   color: &amp;#x27;рыжий&amp;#x27;,
   weight: 3,
   mew: function() {
      console.log(&amp;#x27;мяу-мяу&amp;#x27;);
   },
   sayName() {
      console.log(&amp;#x27;Привет, я кот &amp;#x27; + this.name);
   }
};

catVasya.sayName();
// выведет в консоль: &amp;#x27;Привет, я кот Вася&amp;#x27;&lt;/pre&gt;
  &lt;p&gt;Здесь я специально использовал другой вариант определения метода &lt;code&gt;sayName&lt;/code&gt;, для того, чтобы показать, что в нем ничего страшного. &lt;/p&gt;
  &lt;p&gt;Внутри этого метода мы вызываем &lt;code&gt;this.name&lt;/code&gt;, что фактически означает: &amp;quot;возьми свойство name из текущего объекта&amp;quot;. С помощью &lt;code&gt;this&lt;/code&gt; мы можем обращаться к любым свойствам и к любым методам текущего объекта.&lt;/p&gt;
  &lt;h2&gt;Именование методов&lt;/h2&gt;
  &lt;p&gt;Хотелось бы заострить внимание на одном важном аспекте – именование методов.&lt;/p&gt;
  &lt;p&gt;Если свойства мы всегда называем именем существительным, то методы мы всегда называем используя глаголы. В нашем примере оба добавленных метода имеют глагол в своем названии: &lt;code&gt;mew&lt;/code&gt; – мяукать, &lt;code&gt;sayName&lt;/code&gt; – сказать имя. &lt;/p&gt;
  &lt;p&gt;Всегда называй методы с использованием глаголов, таковы правила и это поможет  различать методы от свойств.&lt;/p&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;h2&gt;Домашнее задание &lt;/h2&gt;
  &lt;p&gt;Добавить несколько методов нашему получившемуся котику, с помощью которых, он мог бы рассказать о своем весе и цвете.&lt;/p&gt;
  &lt;p&gt;Эти методы определить разными способами, о которых написано в статье.   &lt;/p&gt;

</content></entry><entry><id>java-script-stupid:myYxVRS3K</id><link rel="alternate" type="text/html" href="https://teletype.in/@java-script-stupid/myYxVRS3K?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=java-script-stupid"></link><title>Объекты. Свойства.</title><published>2020-04-18T07:14:18.474Z</published><updated>2020-04-21T21:13:50.596Z</updated><summary type="html">&lt;img src=&quot;https://teletype.in/files/03/c2/03c220e5-124c-474f-8351-d2d7005a2525.png&quot;&gt;Всем привет, сегодня пойдет речь об объектах. </summary><content type="html">
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/03/c2/03c220e5-124c-474f-8351-d2d7005a2525.png&quot; width=&quot;1920&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Всем привет, сегодня пойдет речь об объектах. &lt;/p&gt;
  &lt;p&gt;Что такое объекты, зачем они нужны, как их создавать и изменять – обо всем этом в этой статье.&lt;/p&gt;
  &lt;p&gt;Ранее в статьях мы рассматривали примитивные типы (исключением являются массивы). Эти типы важны и нужны, но так как язык JavaScript является объектно-ориентированным(ООП), и в нем часто используются ООП-подходы, то не знать о объектах и не уметь ими пользоваться – огромный пробел в знаниях.&lt;/p&gt;
  &lt;p&gt;Объект – это сложная сущность, которая может хранить в себе целый набор различных данных состоящих из примитивных значений, массивов, функций. &lt;/p&gt;
  &lt;h3&gt;Как создать объект?&lt;/h3&gt;
  &lt;p&gt;Есть несколько способов создать переменную, в которой будет храниться объект. Если нам нужно создать пустой(чистый) объект, то есть 2 варианта: &lt;/p&gt;
  &lt;ol&gt;
    &lt;li&gt;&lt;code&gt;const cat = new Object();&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;const cat = {};&lt;/code&gt;&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p&gt;Синтаксис 1-ого варианта называется &lt;code&gt;конструктором объекта&lt;/code&gt;, а 2-ого – &lt;code&gt;литералом объекта(или литеральной нотацией)&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;Каким вариантом пользоваться? Чаще всего в реальных проектах ты сможешь увидеть 2-ой вариант, т.е. &lt;code&gt;const cat = {};&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;Какие же преимущества есть у объекта? Представим, что мы хотим в коде записать информацию о твоем коте &amp;quot;Ваське&amp;quot;. К примеру нам нужна следующая информация: кличка, возраст, цвет, вес. &lt;/p&gt;
  &lt;p&gt;Как бы ты сейчас стал записывать в коде эти данные? Скорее всего, примерно так:&lt;/p&gt;
  &lt;pre&gt;let catName = &amp;#x27;Васька&amp;#x27;;
let catAge = 2;
let catColor = &amp;#x27;рыжий&amp;#x27;;
let catWeight = 3;&lt;/pre&gt;
  &lt;p&gt;Для того, чтобы записать информацию о котике, мы создали целых 4 переменных. А представь, если тебе нужно будет заполнить данные о каком-то сложном объекте, к примеру о автомобиле, который имеет огромную гору различных характеристик. Создавать 100500 переменных – это очень плохо, как минимум потому, что ты запутаешься в этих переменных очень быстро. &lt;/p&gt;
  &lt;p&gt;Если ты думаешь, что не запутаешься, то представь, что тебе нужно заполнить информацию о трех автомобилях, когда у каждого нужно заполнить по 50 характеристик. Таким методом, на 3 автомобиля у тебя получится 150 переменных. Не хило, неправда ли?&lt;/p&gt;
  &lt;p&gt;А теперь давай представим, что у тебя есть возможность вместо 150 переменных использовать только 3. Как тебе такой вариант? Я думаю, что куда лучше и проще. &lt;/p&gt;
  &lt;p&gt;Вернемся к  Васе. Создаем объект для нашего котика:&lt;/p&gt;
  &lt;pre&gt;const catVasya = {
   name: &amp;#x27;Вася&amp;#x27;,
   age: 2,
   color: &amp;#x27;рыжий&amp;#x27;,
   weight: 3
};&lt;/pre&gt;
  &lt;p&gt;Вуаля, вместо 4-ех переменных получили всего одну с именем &lt;code&gt;cat&lt;/code&gt;. Теперь для того, чтобы вытащить какое-то значение из объекту нужно всего лишь обратится к нужному полю в объекте. Например, мы хотим получить цвет кота из этого объекта:&lt;/p&gt;
  &lt;pre&gt;catVasya.color;&lt;/pre&gt;
  &lt;p&gt;Нужно написать название объекта и через точку указать нужное поле.&lt;/p&gt;
  &lt;h3&gt;Свойства объекта&lt;/h3&gt;
  &lt;p&gt;На самом деле то, что выше я называл &amp;quot;полями&amp;quot; в объекте называется свойствами. В свойстве могут хранится любые примитивные данные(строки, числа, булевские значения) и другие объекты(массивы в JS – тоже имеют тип &lt;code&gt;Object&lt;/code&gt;) . &lt;/p&gt;
  &lt;p&gt;Свойства определяются по данному сценарию: внутри фигурных скобок &lt;code&gt;{...}&lt;/code&gt;, мы должны сначала написать название свойства и, затем, через двоеточие &lt;code&gt;:&lt;/code&gt; указать значение этого свойства:&lt;/p&gt;
  &lt;pre&gt;{
  имяСвойства: &amp;#x27;значение свойства&amp;#x27;,
  имяСвойства2: 5,
  имяСвойства3: true,
  имяСвойства4: [&amp;#x27;а&amp;#x27;, &amp;#x27;б&amp;#x27;, &amp;#x27;в&amp;#x27;],
  имяСвойства5: { 
     //здесь указать свойства другого объекта
  }
}&lt;/pre&gt;
  &lt;p&gt;Как видишь, мы можем записать в свойство объекта любой валидный тип данных, хоть примитивы, хоть массивы, хоть другие объекты. &lt;/p&gt;
  &lt;p&gt;Свойства в обязательном порядке разделяются друг от друга запятой.&lt;/p&gt;
  &lt;p&gt;Хочу обратить внимание, что имя свойства внутри объекта можно определять как в кавычках, так и без них. Посмотри эти 2 скриншота:&lt;/p&gt;
  &lt;figure class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/e0/54/e0544d8b-e270-43f2-91c3-9b0f8fe22a27.png&quot; width=&quot;313&quot; /&gt;
  &lt;/figure&gt;
  &lt;figure class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/79/fd/79fd4d02-1052-4167-8a87-8664673b1f4f.png&quot; width=&quot;322&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;На скриншотах показан один и тот же объект, но с разным подходом в определении имени свойств. Какой правильный?&lt;/p&gt;
  &lt;p&gt;В данном случае, правильным будет использование объекта, где свойства определены без кавычек:&lt;/p&gt;
  &lt;figure class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/e6/f2/e6f280fe-8f9c-4150-be55-53d13d4e86ff.png&quot; width=&quot;313&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Почему? Все просто. Кавычки стоит использовать только тогда, когда ты хочешь задать &amp;quot;необычное&amp;quot; название для свойства. Например:&lt;/p&gt;
  &lt;figure class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/ce/01/ce01ae21-4aad-4bcc-8351-d59fc9ab2a30.png&quot; width=&quot;354&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Я добавил котику свойство с именем &lt;code&gt;other prop&lt;/code&gt; , при этом я отошел от хороших практик JS и не использовал стиль &lt;code&gt;camelCase&lt;/code&gt;, а просто разделил эти слова пробелом. Самое интересное, что не будет никакой ошибки, если такое имя свойства указать в кавычках. Но, если их убрать, то, конечно же, все сломается и объект будет определен некорректно.&lt;/p&gt;
  &lt;p&gt;При этом, если сейчас обратиться к новому свойству через символ точки:&lt;/p&gt;
  &lt;pre&gt;catVasya.other prop;&lt;/pre&gt;
  &lt;p&gt;Мы получим ошибку по той простой причине, что JS просто не поймет, что ты хотел обратиться к этому свойству. Потому что для JS это будет выглядеть как то, что ты пытаешься обратиться к свойству объекта &lt;code&gt;catVasya&lt;/code&gt; с именем &lt;code&gt;other&lt;/code&gt;, затем ставишь пробел и пытаешься обратится к переменной &lt;code&gt;prop&lt;/code&gt;, которая не определена.&lt;/p&gt;
  &lt;p&gt;Поэтому, для того, чтобы обратиться к такому свойству нужно использовать следующий синтаксис:&lt;/p&gt;
  &lt;pre&gt;catVasya[&amp;#x27;other prop&amp;#x27;];&lt;/pre&gt;
  &lt;p&gt;&lt;strong&gt;Данный случай разобран только для примера! Никогда, слышишь!? Никогда не использую в названии свойств объекта символ пробела! Это очень-очень плохо!&lt;/strong&gt;&lt;/p&gt;
  &lt;h3&gt;Вычисляемые свойства&lt;/h3&gt;
  &lt;p&gt;В объекте можно определить свойство, имя которого заранее неизвестно. Звучит страшно непонятно, да? Но сейчас поясню. &lt;/p&gt;
  &lt;p&gt;Представь, что имя свойства заранее неизвестно по той причине, что оно откуда-то приходит позже, либо его вводит пользователь, но нам все-равно нужно его как-то добавить. Объекты в JS позволяют это сделать. &lt;/p&gt;
  &lt;p&gt;Давай будем просить пользователя вводить имя свойства и его значение:&lt;/p&gt;
  &lt;pre&gt;let propName = prompt(&amp;#x27;Введи название свойства&amp;#x27;, &amp;#x27;tailLength&amp;#x27;);
let propValue = prompt(&amp;#x27;Введи значение свойства&amp;#x27;, 20);&lt;/pre&gt;
  &lt;p&gt;Мы завели переменные с именами &lt;code&gt;propName&lt;/code&gt; и &lt;code&gt;propValue&lt;/code&gt;. Оператор &lt;code&gt;prompt&lt;/code&gt; спросит у пользователя как назвать свойство и какое значение в него положить. &lt;/p&gt;
  &lt;p&gt;По умолчанию(если пользователь ничего не укажет), мы запишем свойств &lt;code&gt;tailLength&lt;/code&gt;, что означает &amp;quot;длина хвоста&amp;quot; и передадим в него значение &lt;code&gt;20&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;Давай попробуем добавить данное свойство в объект. Для этого нужно при определении имени свойства обернуть переменную &lt;code&gt;propName&lt;/code&gt; в квадратные скобки и тогда значение этой переменной будет указано как имя свойства объекта, а в само значение свойства нам нужно просто записать переменную &lt;code&gt;propValue&lt;/code&gt; :&lt;/p&gt;
  &lt;figure class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/cf/02/cf026eba-4f6b-49f9-b725-c13a74c70641.png&quot; width=&quot;468&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Надеюсь этот пример наглядно показывает, что добавить свойство с заранее неизвестным именем не так уж и сложно, как может показаться на первый взгляд. &lt;/p&gt;
  &lt;h2&gt;Именование свойств объекта&lt;/h2&gt;
  &lt;p&gt;Важным аспектом является именование свойств объекта. Есть правило, которое говорит о том, что имена свойств должны быть указаны как имена существительные. В нашем примере это: &lt;code&gt;name&lt;/code&gt; – имя, &lt;code&gt;age&lt;/code&gt; – возраст, &lt;code&gt;color&lt;/code&gt; – цвет, &lt;code&gt;weight&lt;/code&gt; – вес.  &lt;/p&gt;
  &lt;p&gt;Здесь очень просто провести аналогию. Свойство любого реального объекта – это какое-либо описание этого объекта: цвет, возраст, рост, запах, вкус и т.д. Все это и всегда является именами существительными. &lt;/p&gt;
  &lt;p&gt;Но, у тебя может быть закрался вопрос у объекта же могут быть способности передвигаться, говорить, летать и производить какие-то другие действия. Как быть с действиями? &lt;/p&gt;
  &lt;p&gt;Действия любых объектов, в переводе на язык программирования – это функции.&lt;/p&gt;
  &lt;p&gt;Но, о функция внутри объекта – в следующей статье.&lt;/p&gt;
  &lt;h2&gt;Домашнее задание&lt;/h2&gt;
  &lt;ol&gt;
    &lt;li&gt;Создать объект &amp;quot;игрушка&amp;quot;&lt;/li&gt;
    &lt;li&gt;Добавить этому объекту свойства &amp;quot;имя&amp;quot;, &amp;quot;материал&amp;quot;&lt;/li&gt;
    &lt;li&gt;Добавить в объект вычисляемое свойство, в котором будет содержаться цена на игрушку.&lt;/li&gt;
  &lt;/ol&gt;

</content></entry><entry><id>java-script-stupid:zoWzakaUH</id><link rel="alternate" type="text/html" href="https://teletype.in/@java-script-stupid/zoWzakaUH?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=java-script-stupid"></link><title>Планирование вызова функции: setInterval</title><published>2020-04-07T16:43:21.846Z</published><updated>2020-04-07T16:43:21.846Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://teletype.in/files/bc/20/bc20b7d2-8845-4f26-82d0-8e86e9280f5d.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://teletype.in/files/cf/86/cf86a697-f7cf-4f4f-9532-74d371914801.png&quot;&gt;Рассмотрим еще один метод для планирования вызова функции – setInterval. </summary><content type="html">
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/cf/86/cf86a697-f7cf-4f4f-9532-74d371914801.png&quot; width=&quot;1920&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Рассмотрим еще один метод для планирования вызова функции – &lt;code&gt;setInterval&lt;/code&gt;. &lt;/p&gt;
  &lt;p&gt;Принцип работы точно такой же как и у его брата &lt;code&gt;setTimeout&lt;/code&gt; (&lt;a href=&quot;https://teletype.in/@java-script-stupid/X8ICeCrVY&quot; target=&quot;_blank&quot;&gt;читать о setTimeout&lt;/a&gt;), за одним небольшим исключением: &lt;code&gt;setInterval&lt;/code&gt; повторяет вызов переданной тобою функции через указанное время.&lt;/p&gt;
  &lt;p&gt;Итак, как и в случае с &lt;code&gt;setTimeout&lt;/code&gt;(&lt;a href=&quot;https://teletype.in/@java-script-stupid/X8ICeCrVY&quot; target=&quot;_blank&quot;&gt;лучше прочитай статью о setTimeout, будет намного понятнее&lt;/a&gt;), &lt;code&gt;setInterval&lt;/code&gt; принимает первым аргументом либо ссылку на функцию, либо функцию, а вторым аргументом передается время в миллисекундах, через которое переодически будет выполняться переданная функция:&lt;/p&gt;
  &lt;pre&gt;function hello() {
   console.log(&amp;#x27;Привет&amp;#x27;);
}

setInterval(hello, 3000);

//каждые 3 секунды в консоль будет выводиться сообщение:
&amp;#x27;Привет&amp;#x27;&lt;/pre&gt;
  &lt;p&gt;Данный метод лучше всего останавливать как только потребность в нем пропадает.&lt;/p&gt;
  &lt;p&gt;&lt;code&gt;setInterval&lt;/code&gt;, как и &lt;code&gt;setTimeout&lt;/code&gt;, возвращает идентификатор, по-которому в дальнейшем можно остановить выполнение &lt;code&gt;setInterval&lt;/code&gt;:&lt;/p&gt;
  &lt;pre&gt;function hello() {
   console.log(&amp;#x27;Привет&amp;#x27;);
}

const intervalId = setInterval(hello, 3000);

// команда ниже остановит выполнение setInterval
clearInterval(intervalId);&lt;/pre&gt;
  &lt;p&gt;Давай попробуем выполнить следующую задачу: с помощью &lt;code&gt;setInterval&lt;/code&gt; выведем в консоль слово &lt;code&gt;&amp;quot;Привет&amp;quot;&lt;/code&gt; 3 раза. Каждое слово должно появляться через секунду после предыдущего. Код:&lt;/p&gt;
  &lt;pre&gt;let counter = 0;

function hello() {
   console.log(&amp;#x27;Привет&amp;#x27;);

   counter += 1;
   
   if (counter === 3) {
      clearInterval(intervalId);
   }
}

const intervalId = setInterval(hello, 1000);&lt;/pre&gt;
  &lt;p&gt;Итак, мы определили функцию &lt;code&gt;hello&lt;/code&gt;, которую затем передали в качестве первого аргумента в метод &lt;code&gt;setInterval&lt;/code&gt;, а вторым аргументом указали время &lt;code&gt;1000&lt;/code&gt; мс (1 секунда) через которое постоянно нужно запускать функцию &lt;code&gt;hello&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;Также мы определили переменную &lt;code&gt;counter&lt;/code&gt; (счетчик),  которая будет считать количество запусков функции &lt;code&gt;hello&lt;/code&gt; (напомню, по условию нам нужно запустить эту функцию только 3 раза). &lt;/p&gt;
  &lt;p&gt;В самой функции &lt;code&gt;hello&lt;/code&gt;:&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;мы сначала выводим в консоль слово &lt;code&gt;&amp;quot;Привет&amp;quot;&lt;/code&gt;;&lt;/li&gt;
    &lt;li&gt;затем увеличиваем значение счетчика;&lt;/li&gt;
    &lt;li&gt;затем строгим сравнением проверяем не равен ли счетчик значению &lt;code&gt;3&lt;/code&gt;. Если условие выполняется, значит слово &lt;code&gt;&amp;quot;Привет&amp;quot;&lt;/code&gt; было выведено 3 раза и нам нужно остановить выполнение &lt;code&gt;setInterval&lt;/code&gt;, для этого нам поможет метод &lt;code&gt;clearInterval&lt;/code&gt;. &lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;Результат:&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/92/5c/925c81e2-482b-4819-88be-2d0709fa8d17.png&quot; width=&quot;786&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Перед словом &lt;code&gt;&amp;quot;Привет&amp;quot;&lt;/code&gt; стоит цифра 3, а это значит, что данная надпись трижды выводилась в консоль (так браузер сворачивает одинаковые значения выводимые в консоль, чтобы уменьшить количество &amp;quot;мусора&amp;quot;)&lt;/p&gt;
  &lt;p&gt;Собственно и все. Задача выполнена. Обязательно повтори ее на практике!&lt;/p&gt;

</content></entry><entry><id>java-script-stupid:X8ICeCrVY</id><link rel="alternate" type="text/html" href="https://teletype.in/@java-script-stupid/X8ICeCrVY?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=java-script-stupid"></link><title>Планирование вызова функции: setTimeout</title><published>2020-04-02T08:01:41.087Z</published><updated>2020-04-02T08:06:39.172Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://teletype.in/files/32/5e/325e50ea-8160-4dce-87cc-c2236dd19198.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://teletype.in/files/64/4d/644deafc-2744-4cfc-8c53-c8a71832c269.png&quot;&gt;Представь, что у тебя есть задача вывести приветственное сообщение пользователю через 5 секунд после того, как он перешел на страницу. Как это организовать средствами JavaScript?</summary><content type="html">
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/64/4d/644deafc-2744-4cfc-8c53-c8a71832c269.png&quot; width=&quot;1920&quot; /&gt;
  &lt;/figure&gt;
  &lt;p&gt;Представь, что у тебя есть задача вывести приветственное сообщение пользователю через 5 секунд после того, как он перешел на страницу. Как это организовать средствами JavaScript?&lt;/p&gt;
  &lt;p&gt;В этом вопросе нам поможет метод объекта &lt;code&gt;window&lt;/code&gt; – &lt;code&gt;setTimeout()&lt;/code&gt;. Этот метод запускает через указанное в аргументах время, указанную в аргументах функцию. Пример использования: &lt;/p&gt;
  &lt;pre&gt;// 1-ый вариант использования
window.setTimeout(func, delay);

// 2-ой вариант использования
setTimeout(func, delay);&lt;/pre&gt;
  &lt;p&gt;Как видишь, данный метод объекта &lt;code&gt;window&lt;/code&gt; можно вызывать и как обычную функцию (2-ой вариант использования). Я, кстати, рекомендую использовать именно 2-ой вариант, так как он чаще всего встречается и используется.&lt;/p&gt;
  &lt;p&gt;В качестве аргументов мы передаем &lt;code&gt;func&lt;/code&gt; и &lt;code&gt;delay&lt;/code&gt;, где &lt;code&gt;func&lt;/code&gt; – это функция, либо ссылка на функцию, которую должен запустить &lt;code&gt;setTimeout&lt;/code&gt; после того, как пройдет время &lt;code&gt;delay&lt;/code&gt; (указывается в миллисекундах). &lt;em&gt;&lt;strong&gt;Кстати, такие функции, которые передаются в другие функции в качестве аргументов – называются callback-функциями или функциями обратного вызова.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
  &lt;p&gt;Теперь вернемся к нашей задаче поставленной в начале статьи и поприветствуем пользователя:&lt;/p&gt;
  &lt;pre&gt;function hello() {
   alert(&amp;#x27;Привет!&amp;#x27;);
}

setTimeout(hello, 5000);&lt;/pre&gt;
  &lt;p&gt;Функция &lt;code&gt;hello&lt;/code&gt;, в данном примере, является callback-функцией, которую нужно запустить после того как пройдет 5000 миллисекунд (5 секунд). В данном примере, в качестве первого аргумента, мы передали ссылку на функцию &lt;code&gt;hello&lt;/code&gt;. Ссылка на функцию – это ее имя, а не вызов. Т.е.:&lt;/p&gt;
  &lt;pre&gt;hello; // - это ссылка на функцию
hello(); // - это вызов функции&lt;/pre&gt;
  &lt;p&gt;&lt;strong&gt;В качестве аргумента мы должны передавать либо ссылку на функцию, либо описание функции(смотри ниже), но никогда не должны передавать вызов функции!&lt;/strong&gt;&lt;/p&gt;
  &lt;p&gt;Есть и другие варианты передачи callback-функции, которые делают ровно тоже самое.&lt;/p&gt;
  &lt;p&gt;В качестве первого аргумента, мы можем передать анонимную(безымянную) функцию:&lt;/p&gt;
  &lt;pre&gt;setTimeout(function() { alert(&amp;#x27;Привет!&amp;#x27;); }, 5000);&lt;/pre&gt;
  &lt;p&gt;Так же можем передать анонимную стрелочную функцию:&lt;/p&gt;
  &lt;pre&gt;setTimeout(() =&amp;gt; alert(&amp;#x27;Привет!&amp;#x27;), 5000);&lt;/pre&gt;
  &lt;p&gt;Небольшое отступление: использование анонимных функций позволяет не описывать callback-функцию в глобальной области видимости, т.е. анонимная функция, описание которой ты передашь в качестве первого аргумента будет доступна только для &lt;code&gt;setTimeout&lt;/code&gt;, и не доступна ни для кого извне, что, иногда, является лучшим решением.&lt;/p&gt;
  &lt;p&gt;Продолжим.&lt;/p&gt;
  &lt;p&gt;Самое интересное, что мы можем передать строку, вместо функции и она выполнится:&lt;/p&gt;
  &lt;pre&gt;setTimeout(&amp;#x60;alert(&amp;#x27;Привет!&amp;#x27;)&amp;#x60;, 5000);&lt;/pre&gt;
  &lt;p&gt;&lt;strong&gt;Все варианты выполняют одну и ту же задачу, но, последний вариант с передачей строки:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre&gt;setTimeout(&amp;#x60;alert(&amp;#x27;Привет!&amp;#x27;)&amp;#x60;, 5000);&lt;/pre&gt;
  &lt;p&gt;&lt;strong&gt;использовать не рекомендуется&lt;/strong&gt;, так как это и стилистически не красиво и в плане безопасности – это плохой вариант. Стоит запомнить, что такой вариант может встретиться в чужом коде, но &lt;strong&gt;в своем такое писать не стоит&lt;/strong&gt;. &lt;/p&gt;
  &lt;p&gt;Последнее что хотелось бы отметить, так это то, что метод setTimeout нужно удалять, чтобы не произошло утечки памяти. Делается это достаточно просто. &lt;/p&gt;
  &lt;p&gt;&lt;code&gt;setTimeout&lt;/code&gt; на самом деле еще и возвращает данные, а именно, он возвращает свой идентификатор. Стоит понимать, что у каждого &lt;code&gt;setTimeout&lt;/code&gt; этот идентификатор свой, индивидуальный.&lt;/p&gt;
  &lt;p&gt;Чтобы не произошло утечки памяти, нужно удалять &lt;code&gt;setTimeout&lt;/code&gt; после выполнения. Сделать этом можно с помощью &lt;code&gt;clearTimeout(id)&lt;/code&gt;, где в качестве аргумента нужно передать идентификатор вашего &lt;code&gt;setTimeout&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;Для начала давай сохраним идентификатор нашего setTimeout в константе &lt;code&gt;timerId&lt;/code&gt;:&lt;/p&gt;
  &lt;pre&gt;function hello() {
   alert(&amp;#x27;Привет&amp;#x27;);
}

const timerId = setTimeout(hello, 5000); &lt;/pre&gt;
  &lt;p&gt;Удалить setTimeout из памяти нам нужно после выполнения приветствия, поэтому добавим clearInterval в функцию hello, после вывода приветствия:&lt;/p&gt;
  &lt;pre&gt;function hello() {
   alert(&amp;#x27;Привет&amp;#x27;);
   clearInterval(timerId);
}

const timerId = setTimeout(hello, 5000); &lt;/pre&gt;
  &lt;p&gt;Все, теперь после выполнения приветствия &lt;code&gt;setTimeout&lt;/code&gt; будет удален из памяти.&lt;/p&gt;
  &lt;p&gt;Еще один небольшой пример:&lt;/p&gt;
  &lt;pre&gt;function hello() {
   alert(&amp;#x27;Привет&amp;#x27;);
}

const timerId = setTimeout(hello, 5000);
clearInterval(timerId);&lt;/pre&gt;
  &lt;p&gt;В данном случае &lt;code&gt;setTimeout&lt;/code&gt; не будет выполнен совсем, потому что мы вызвали &lt;code&gt;cleatInterval&lt;/code&gt; сразу же после объявления &lt;code&gt;setTimeout&lt;/code&gt;, эти действием мы как бы отменили(удалили) &lt;code&gt;setTimeout&lt;/code&gt;.&lt;/p&gt;

</content></entry><entry><id>java-script-stupid:FSxPHRy1</id><link rel="alternate" type="text/html" href="https://teletype.in/@java-script-stupid/FSxPHRy1?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=java-script-stupid"></link><title>Методы массивов: flat, fill</title><published>2020-02-17T14:06:09.394Z</published><updated>2020-02-17T14:06:09.394Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://teletype.in/files/44/be/44be458e-2dab-4a0c-9079-2494b94f5357.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://teletype.in/files/c8/42/c842462a-84ee-4b27-81e0-c5c7333b6fa8.png&quot;&gt;Данный метод появился недавно, но он очень крут. Он создает новый массив из всех подмассивов содержащихся в нем уменьшая мерность на указанное значение(по умолчанию 1). Наверное звучит очень сложно и запутанно и, скорее всего, прямо сейчас ты мало где сможешь применить данный метод на практике. Но пример все-равно давай посмотрим:</summary><content type="html">
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/c8/42/c842462a-84ee-4b27-81e0-c5c7333b6fa8.png&quot; width=&quot;1920&quot; /&gt;
  &lt;/figure&gt;
  &lt;h3&gt;Метод flat&lt;/h3&gt;
  &lt;p&gt;Данный метод появился недавно, но он очень крут. Он создает новый массив из всех подмассивов содержащихся в нем уменьшая мерность на указанное значение(по умолчанию 1). Наверное звучит очень сложно и запутанно и, скорее всего, прямо сейчас ты мало где сможешь применить данный метод на практике. Но пример все-равно давай посмотрим:&lt;/p&gt;
  &lt;pre&gt;const arr = [1, 2, 3, [4, 5], [[7,8]]];
const transformArr = arr.flat();

transformArr; //[1, 2, 3, 4, 5, [7, 8]]&lt;/pre&gt;
  &lt;p&gt;Как видишь, массив &lt;code&gt;arr&lt;/code&gt; был преобразован в новый.  Как ты можешь заметить, все подмассивы, которые были внутри массива &lt;code&gt;arr&lt;/code&gt; как бы &amp;quot;распаковались&amp;quot; на 1 уровень вложенности. Если третьим элементом в массиве arr был массив &lt;code&gt;[4, 5]&lt;/code&gt;, то сейчас он распаковался и перестал существовать как массив. &lt;/p&gt;
  &lt;p&gt;В этом же массиве &lt;code&gt;arr&lt;/code&gt; 4-ым элементом был массив с массивом (т.е. это 2 уровня вложенности), но теперь он выглядит как простой массив&lt;code&gt; [7, 8]&lt;/code&gt;, т.е. начальный массив с массивом распаковался в обычный массив (один уровень вложенности исчез).&lt;/p&gt;
  &lt;p&gt;Этот уровень &amp;quot;сглаживания&amp;quot; вложенности, который, повторюсь, по умолчанию равен &lt;code&gt;1&lt;/code&gt; – может быть задан. Для этого в метод &lt;code&gt;flat&lt;/code&gt; нужно передать число, которое и будет являться этим уровнем &amp;quot;сглаживания&amp;quot;. &lt;/p&gt;
  &lt;p&gt;Так как мы не всегда можем знать уровень вложенности подмассивов, мы можем указать в качестве параметра значение бесконечности – &lt;code&gt;Infinity&lt;/code&gt;. Это позволит нам убрать абсолютно все вложенности во всех подмассивах. Пример:&lt;/p&gt;
  &lt;pre&gt;const arr = [1, 2, 3, [4, 5], [[7,8]]];
const transformArr = arr.flat(Infinity);

transformArr; //[1, 2, 3, 4, 5, 7, 8]&lt;/pre&gt;
  &lt;p&gt;Какие бы глубины вложенности не были теперь массивы внутри массива &lt;code&gt;arr&lt;/code&gt;, они всегда будут распакованы в один одноуровневый массив.&lt;/p&gt;
  &lt;h3&gt;Метод fill&lt;/h3&gt;
  &lt;p&gt;Метод &lt;code&gt;fill&lt;/code&gt; заменяет или заполняет элементы массива одним и тем же значением. Для замены или заполнения конкретных отрезков массива можно указать индексы начального и конечного элементов, которые требуют заполнения/замены.&lt;/p&gt;
  &lt;pre&gt;const arr = [1, 2, 3, 4];
arr.fill(0, 2, 4)

arr; // [1, 2, 0, 0]&lt;/pre&gt;
  &lt;p&gt;Рассмотрим вызов метода:&lt;/p&gt;
  &lt;pre&gt;arr.fill(0, 2, 4)&lt;/pre&gt;
  &lt;p&gt;&lt;u&gt;Первый аргумент&lt;/u&gt; – значение, которым заполнять/заменять элементы массива;&lt;/p&gt;
  &lt;p&gt;&lt;u&gt;Второй аргумент&lt;/u&gt; – индекс после которого начинать вставлять указанное значение;&lt;/p&gt;
  &lt;p&gt;&lt;u&gt;Третий аргумент&lt;/u&gt; – индекс до которого вставлять указанное значение.&lt;/p&gt;
  &lt;p&gt;Получаем:&lt;/p&gt;
  &lt;pre&gt;arr; // [1, 2, 0, 0]&lt;/pre&gt;
  &lt;p&gt;Что полностью соответствует ожиданиям.&lt;/p&gt;

</content></entry><entry><id>java-script-stupid:R-LF464E</id><link rel="alternate" type="text/html" href="https://teletype.in/@java-script-stupid/R-LF464E?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=java-script-stupid"></link><title>Методы массивов: Array.isArray, some, every</title><published>2020-02-17T14:01:50.528Z</published><updated>2020-02-17T14:01:50.528Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://teletype.in/files/89/16/8916a4f3-9b1f-455e-814c-5bc05d08bb9c.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://teletype.in/files/c1/80/c1803912-7e57-4693-b0d0-828ae4890cbf.png&quot;&gt;Порой требуется понять, являются ли данные, которые, например, пришли с сервера – массивом. Как мы можем это узнать? Существует оператор typeof, но в  JS нет отдельного типа для массивов. JS не различает массив от объекта: для него и то и другое – объекты. Но задачу как-то надо решать, именно для этого и существует статический метод isArray в объекте Array.</summary><content type="html">
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/c1/80/c1803912-7e57-4693-b0d0-828ae4890cbf.png&quot; width=&quot;1920&quot; /&gt;
  &lt;/figure&gt;
  &lt;h3&gt;Метод Array.isArray&lt;/h3&gt;
  &lt;p&gt;Порой требуется понять, являются ли данные, которые, например, пришли с сервера – массивом. Как мы можем это узнать? Существует оператор typeof, но в  JS нет отдельного типа для массивов. JS не различает массив от объекта: для него и то и другое – объекты. Но задачу как-то надо решать, именно для этого и существует статический метод &lt;code&gt;isArray&lt;/code&gt; в объекте &lt;code&gt;Array&lt;/code&gt;.&lt;/p&gt;
  &lt;pre&gt;const obj = {name: &amp;#x27;Толян&amp;#x27;};
const arr = [1, 2, 3];

Array.isArray(arr); //true
Array.isArray(obj); //false&lt;/pre&gt;
  &lt;h3&gt;Метод some&lt;/h3&gt;
  &lt;p&gt;Представим, что у тебя есть массив чисел. При этом, предположим, что на момент работы с массивом ты точно не знаешь, какими числами он заполнен. &lt;/p&gt;
  &lt;p&gt;И тебе нужно узнать, что в массиве есть хотя бы один элемент, который можно разделить на 2 и полученное значению будет больше, либо равно 10. &lt;/p&gt;
  &lt;p&gt;В голову может прийти множество вариантов решений. Но метод &lt;code&gt;some&lt;/code&gt; подойдет тут намного лучше: &lt;/p&gt;
  &lt;pre&gt;const numbers = [20, 45, 12, -4, 5, 7];

const has = numbers.some(n =&amp;gt; (n/2) &amp;gt;= 10);

has; // true&lt;/pre&gt;
  &lt;p&gt;В данном случае под наше условие подойдет даже 2 числа &lt;code&gt;20&lt;/code&gt; и &lt;code&gt;45&lt;/code&gt;, поэтому метод выдаст нам &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;
  &lt;h3&gt;Метод every&lt;/h3&gt;
  &lt;p&gt;Метод &lt;code&gt;every&lt;/code&gt; похож на метод &lt;code&gt;some&lt;/code&gt;. Но, по названию должно быть понятно, что метод &lt;code&gt;every&lt;/code&gt; вернет &lt;code&gt;true&lt;/code&gt; только в том случае, если все элементы массива подходят под заданное условие.&lt;/p&gt;
  &lt;p&gt;Давай проверим каждый элемент массива на условие: каждый элемент делится 2 и полученное значение больше или равно 10.&lt;/p&gt;
  &lt;pre&gt;const numbers = [20, 30, 40];
const otherNumbers = [20, 10, 40];

const hasInNumbers = numbers.every(n =&amp;gt; (n/2) &amp;gt;= 10);
const hasInOtherNumbers = otherNumbers.every(n =&amp;gt; (n/2) &amp;gt;= 10);

hasInNumbers; // true
hasInOtherNumbers; //false&lt;/pre&gt;
  &lt;p&gt;Все элементы массива &lt;code&gt;numbers&lt;/code&gt; подходят под условие – поэтому метод &lt;code&gt;every&lt;/code&gt; выдает нам значение &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;
  &lt;p&gt;А вот в массиве &lt;code&gt;otherNumbers&lt;/code&gt; под условие не подходит значение &lt;code&gt;10&lt;/code&gt;, поэтому &lt;code&gt;every&lt;/code&gt; возвратит – &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;

</content></entry></feed>