<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xmlns:tt="http://teletype.in/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>JavaScript для тупых</title><generator>teletype.in</generator><description><![CDATA[JavaScript для тупых]]></description><image><url>https://teletype.in/files/6e/6e99fa57-98f2-4998-9459-5129ea0bf822.png</url><title>JavaScript для тупых</title><link>https://teletype.in/@java-script-stupid</link></image><link>https://teletype.in/@java-script-stupid?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=java-script-stupid</link><atom:link rel="self" type="application/rss+xml" href="https://teletype.in/rss/java-script-stupid?offset=0"></atom:link><atom:link rel="next" type="application/rss+xml" href="https://teletype.in/rss/java-script-stupid?offset=10"></atom:link><atom:link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></atom:link><pubDate>Sat, 13 Jun 2026 03:37:03 GMT</pubDate><lastBuildDate>Sat, 13 Jun 2026 03:37:03 GMT</lastBuildDate><item><guid isPermaLink="true">https://teletype.in/@java-script-stupid/8AOVBrgl1</guid><link>https://teletype.in/@java-script-stupid/8AOVBrgl1?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=java-script-stupid</link><comments>https://teletype.in/@java-script-stupid/8AOVBrgl1?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=java-script-stupid#comments</comments><dc:creator>java-script-stupid</dc:creator><title>Promises (Обещания)</title><pubDate>Fri, 22 May 2020 16:16:28 GMT</pubDate><media:content medium="image" url="https://teletype.in/files/f8/25/f825a4eb-80e0-4261-bad6-b19911a09338.png"></media:content><description><![CDATA[<img src="https://teletype.in/files/6f/28/6f28658c-1e6f-401d-92b5-2beeb5660a8b.png"></img>Всем привет. На повестке сегодняшнего дня – Promises.]]></description><content:encoded><![CDATA[
  <figure class="m_original">
    <img src="https://teletype.in/files/6f/28/6f28658c-1e6f-401d-92b5-2beeb5660a8b.png" width="1920" />
  </figure>
  <p>Всем привет. На повестке сегодняшнего дня – <code>Promises</code>.</p>
  <p>У многих возникает много непонимания как работать с обещаниями, а у многие даже не понимают зачем они вообще нужны. В этой статье, я, как и всегда, постараюсь максимально просто и на примерах рассказать о обещаниях. Надеюсь, что после прочтения этой статьи ты больше никогда не будешь прятаться от <code>Promises</code>, ведь они совсем не страшные =)</p>
  <h3>Начнем</h3>
  <p>Хотелось бы начать с того, что JS язык синхронный, т.е. весь код выполняется последовательно. И все было бы хорошо, но достаточно быстро в языке появилась потребность в дополнительных возможностях, а именно, понадобилась асинхронность. Зачем?</p>
  <p>Все мы сидим в социальных сетях. Когда ты заходишь, например, в Facebook, то наверное, замечал, что сайт загружается за несколько секунд, а не &quot;висит&quot; по несколько минут. Но все бы сайты, тем более такие крупные как Facebook без асинхронных операций загружались бы очень долго. </p>
  <p>Ведь когда ты заходишь на Facebook – браузер отсылает очень много запросов на сервера соц.сети, чтобы получить какие-то данные, например, фотографию твоего профиля, информацию из этого профиля, личные сообщения, списки друзей и т.п. На все это нужно время, и если бы все эти запросы выполнялись друг за другом, т.е. каждый бы запрос ожидал завершения предыдущего – это был бы ад.</p>
  <p>Благодаря асинхронности, все запросы отсылаются одновременно и весь остальной код не ждет ответа от них, а продолжает выполняться. Когда же асинхронная операция заканчивает свое выполнение – отрабатывает какая-либо заранее подготовленная функция, которая, например, отобразит блок с твоими друзьями или все сообщения в определенном диалоге.</p>
  <h3>Какие асинхронные операции мы знаем?</h3>
  <p>Я уже писал о асинхронных методах в JS, а конкретно: <code>setInterval</code> и <code>setTimeout</code>. </p>
  <p>Это яркие представители асинхронного исполнения кода. Если не читал о них, то советую прочитать (делай тык):</p>
  <ul>
    <li><code><a href="https://teletype.in/@java-script-stupid/X8ICeCrVY" target="_blank">setInterval</a></code></li>
    <li><code><a href="https://teletype.in/@java-script-stupid/X8ICeCrVY" target="_blank">setTimeout</a></code></li>
  </ul>
  <h3>Эмуляция работы с сервером с помощью setTimeout</h3>
  <p>Итак, давай попробуем сэмулировать работу с сервером. Сначала, сделаем это с помощью <code>setTimeout</code>, а затем с помощью <code>Promise</code> и, как итог, поймем в чем разница и рассмотрим все плюсы <code>Promise</code>.</p>
  <p>Представим, что мы отсылаем запрос на сервер. Сервер собирает данные (на это уходит какое-то время) и сервер высылает нам данные (это тоже занимает время).</p>
  <p>Пошли к коду:</p>
  <pre>console.log(&#x27;Отправляем запрос на сервер...&#x27;);

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

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

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

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

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

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

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

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

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

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

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

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

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@java-script-stupid/DH4eLd2VF</guid><link>https://teletype.in/@java-script-stupid/DH4eLd2VF?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=java-script-stupid</link><comments>https://teletype.in/@java-script-stupid/DH4eLd2VF?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=java-script-stupid#comments</comments><dc:creator>java-script-stupid</dc:creator><title>Прототипы</title><pubDate>Thu, 14 May 2020 13:35:40 GMT</pubDate><media:content medium="image" url="https://teletype.in/files/de/5b/de5b9eaa-0e3b-4181-b5e9-32463e28b746.png"></media:content><description><![CDATA[<img src="https://teletype.in/files/aa/1b/aa1bc674-3b76-4a2e-8413-b40d264e6169.png"></img>Сегодня речь пойдет о прототипах. Чтобы лучше все понять – создаем сразу же простой объект.]]></description><content:encoded><![CDATA[
  <figure class="m_original">
    <img src="https://teletype.in/files/aa/1b/aa1bc674-3b76-4a2e-8413-b40d264e6169.png" width="1920" />
  </figure>
  <p>Сегодня речь пойдет о прототипах. Чтобы лучше все понять – создаем сразу же простой объект.</p>
  <pre>const cat = {
    name: &#x27;Кот&#x27;,
    weight: 3,
    meow: function() {
      console.log(&#x27;meow&#x27;);
    }
};

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

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

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@java-script-stupid/KNNOyrWSY</guid><link>https://teletype.in/@java-script-stupid/KNNOyrWSY?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=java-script-stupid</link><comments>https://teletype.in/@java-script-stupid/KNNOyrWSY?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=java-script-stupid#comments</comments><dc:creator>java-script-stupid</dc:creator><title>Замыкания</title><pubDate>Thu, 07 May 2020 19:07:36 GMT</pubDate><media:content medium="image" url="https://teletype.in/files/bd/6f/bd6f10bf-7daa-444f-bfed-5a4656d57455.png"></media:content><description><![CDATA[<img src="https://teletype.in/files/d5/2b/d52b57e9-6e40-478f-bf89-3432e852ced6.png"></img>Сегодня речь пойдет о замыканиях в JavaScript. Для многих эта тема подсознательно воспринимается непонятной и от того сложной. Но, в действительности, в замыканиях нет ничего страшного и сложного.]]></description><content:encoded><![CDATA[
  <figure class="m_original">
    <img src="https://teletype.in/files/d5/2b/d52b57e9-6e40-478f-bf89-3432e852ced6.png" width="1920" />
  </figure>
  <p>Сегодня речь пойдет о замыканиях в JavaScript. Для многих эта тема подсознательно воспринимается непонятной и от того сложной. Но, в действительности, в замыканиях нет ничего страшного и сложного.</p>
  <p>Что же такое замыкание? Если говорить простыми словами, то это просто функция в функции. Вот и все. Да-да. Так вот просто. Это функция, которая находится внутри другой функции.</p>
  <p>Начнем сразу же с примеров, т.к. на них будет разобраться намного проще. </p>
  <pre>function hi() {
    return function() {
        console.log(&#x27;Привет&#x27;);
    }
}</pre>
  <p>Такая вот незамысловатая конструкция: у нас имеется функция <code>hi</code>, которая возвращает другую функцию.</p>
  <p>Получается, что если вызвать функцию <code>hi</code>, то может показаться, что ничего не произошло, так как в консоль не будет выведено слово <code>Привет</code>:</p>
  <pre>hi(); // в консоль ничего не выведется</pre>
  <p>Так как функция hi возвращает новую функцию, то нам нужно ее вызвать, перед эти, для наглядности запишем ее в константу и вызовем ее:</p>
  <pre>const sayHi = hi();

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

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

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@java-script-stupid/ZYjyvsU9f</guid><link>https://teletype.in/@java-script-stupid/ZYjyvsU9f?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=java-script-stupid</link><comments>https://teletype.in/@java-script-stupid/ZYjyvsU9f?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=java-script-stupid#comments</comments><dc:creator>java-script-stupid</dc:creator><title>this, call, apply, bind</title><pubDate>Sun, 03 May 2020 09:34:05 GMT</pubDate><media:content medium="image" url="https://teletype.in/files/97/71/97712f26-b6cb-454c-a5fa-73f1b9293ccb.png"></media:content><description><![CDATA[<img src="https://teletype.in/files/84/58/8458f706-6711-4671-8d9a-2b1d1fff87e6.png"></img>Сегодня хотелось бы рассказать о таких надуманно сложных вещах как call, bind, apply, ну и, соответственно, затронуть this. Все эти слова связаны одним словом – контекст. Но, обо всем по-порядку.]]></description><content:encoded><![CDATA[
  <figure class="m_original">
    <img src="https://teletype.in/files/84/58/8458f706-6711-4671-8d9a-2b1d1fff87e6.png" width="1920" />
  </figure>
  <p>Сегодня хотелось бы рассказать о таких надуманно сложных вещах как <code>call</code>, <code>bind</code>, <code>apply</code>, ну и, соответственно, затронуть <code>this</code>. Все эти слова связаны одним словом – контекст. Но, обо всем по-порядку.</p>
  <p>Многие боятся даже подходить к этой теме потому что им кажется, что это что-то невероятно сложное и непонятное. Поэтому, надеюсь, что сегодня я развенчаю все ваши страхи и непонятки по этой теме.</p>
  <p>Все примеры будут сделаны на основе функций, поэтому нужно представлять как работают функции.</p>
  <p>Статьи о функциях: <a href="https://teletype.in/@java-script-stupid/SJ_9z4R6B" target="_blank">Функции</a>, <a href="https://teletype.in/@java-script-stupid/r1pKooU0H" target="_blank">Функции. Возврат значения</a></p>
  <h2>Ключевое слово this</h2>
  <p>Создадим обычную функцию и сразу же вызовем ее:</p>
  <pre>function hi() {
    console.log(&#x27;Привет&#x27;, this);
}

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

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

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

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

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

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

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

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

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@java-script-stupid/yTEvPMH9B</guid><link>https://teletype.in/@java-script-stupid/yTEvPMH9B?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=java-script-stupid</link><comments>https://teletype.in/@java-script-stupid/yTEvPMH9B?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=java-script-stupid#comments</comments><dc:creator>java-script-stupid</dc:creator><title>Объекты. Методы</title><pubDate>Tue, 21 Apr 2020 21:18:15 GMT</pubDate><media:content medium="image" url="https://teletype.in/files/2b/44/2b443aa0-111f-42e4-a637-f0afcb76ebe1.png"></media:content><description><![CDATA[<img src="https://teletype.in/files/a2/d2/a2d2d1ff-56fb-4596-a300-6b830e4b6e4f.png"></img>Продолжаем тему объектов и сегодня на повестке дня – методы. ]]></description><content:encoded><![CDATA[
  <figure class="m_original">
    <img src="https://teletype.in/files/a2/d2/a2d2d1ff-56fb-4596-a300-6b830e4b6e4f.png" width="1920" />
  </figure>
  <p>Продолжаем тему объектов и сегодня на повестке дня – методы. </p>
  <h2>Что такое метод объекта?</h2>
  <p>На самом деле метод – это обычная функция. Да, ничего сверхъестественного и страшного. Обычная, особо ничем не примечательная функция, которая просто напросто находится внутри объекта и как-то связана с самим этим объектом. </p>
  <h2>Добавление метода</h2>
  <p>В <a href="https://teletype.in/@java-script-stupid/myYxVRS3K" target="_blank">прошлой статье</a> мы рассматривали свойства объекта и создали объект котика:</p>
  <pre>const catVasya = {
   name: &#x27;Вася&#x27;,
   age: 2,
   color: &#x27;рыжий&#x27;,
   weight: 3
};</pre>
  <p>Так вот, мы имеем имя котика, его возраст, цвет и вес. Получается, что мы дали котику некое описание, но вот делать наш котик пока что ничего не умеет. </p>
  <p>Чтобы он что-то научился делать нам нужно добавить в объект метод (функцию). Давай научим котика мяукать, для этого добавим в объект метод под названием <code>mew</code>:</p>
  <pre>const catVasya = {
   name: &#x27;Вася&#x27;,
   age: 2,
   color: &#x27;рыжий&#x27;,
   weight: 3,
   mew: function() {
      console.log(&#x27;мяу-мяу&#x27;);
   }
};</pre>
  <p>Как видишь, функция в объект добавляется точно так же как и обычное свойство, за тем исключением, что значение этого свойства – функция.</p>
  <p>Правда, хочу заметить, что это не единственный способ определить метод внутри объекта. Очень часто ты можешь увидеть такую запись:</p>
  <pre>mew() {
  console.log(&#x27;мяу-мяу&#x27;);
}</pre>
  <p>Эта запись считается краткой и используется достаточно часто. </p>
  <h2>Вызов метода</h2>
  <p>Теперь у получившегося объекта мы можем вызвать данный метод как обычную функцию:</p>
  <pre>catVasya.mew();
// выведет в консоль: &#x27;мяу-мяу&#x27;</pre>
  <p>В целом, все очень просто. Но, согласись, если бы на этом все заканчивалось, то особого смысла в методах и не было бы. Но, есть одна очень ценная вещь, которую умеют методы – обращаться к другим свойствам и методам того же объекта.</p>
  <p>Давай представим, что мы попали в сказочную страну, где животные разговаривают. Следственно, наш кот, может сказать, как его зовут. Поэтому, добавим ему такую возможность добавив в наш объект метод <code>sayName</code>. </p>
  <p>Внутри объекта лежит свойство <code>name</code>, следственно, из метода <code>sayName</code> нам как-то нужно &quot;достучаться&quot; до этого свойства. Делается это просто, с помощью ключевого свойства <code>this</code>:</p>
  <pre>const catVasya = {
   name: &#x27;Вася&#x27;,
   age: 2,
   color: &#x27;рыжий&#x27;,
   weight: 3,
   mew: function() {
      console.log(&#x27;мяу-мяу&#x27;);
   },
   sayName() {
      console.log(&#x27;Привет, я кот &#x27; + this.name);
   }
};

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

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

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@java-script-stupid/zoWzakaUH</guid><link>https://teletype.in/@java-script-stupid/zoWzakaUH?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=java-script-stupid</link><comments>https://teletype.in/@java-script-stupid/zoWzakaUH?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=java-script-stupid#comments</comments><dc:creator>java-script-stupid</dc:creator><title>Планирование вызова функции: setInterval</title><pubDate>Tue, 07 Apr 2020 16:43:21 GMT</pubDate><media:content medium="image" url="https://teletype.in/files/bc/20/bc20b7d2-8845-4f26-82d0-8e86e9280f5d.png"></media:content><description><![CDATA[<img src="https://teletype.in/files/cf/86/cf86a697-f7cf-4f4f-9532-74d371914801.png"></img>Рассмотрим еще один метод для планирования вызова функции – setInterval. ]]></description><content:encoded><![CDATA[
  <figure class="m_original">
    <img src="https://teletype.in/files/cf/86/cf86a697-f7cf-4f4f-9532-74d371914801.png" width="1920" />
  </figure>
  <p>Рассмотрим еще один метод для планирования вызова функции – <code>setInterval</code>. </p>
  <p>Принцип работы точно такой же как и у его брата <code>setTimeout</code> (<a href="https://teletype.in/@java-script-stupid/X8ICeCrVY" target="_blank">читать о setTimeout</a>), за одним небольшим исключением: <code>setInterval</code> повторяет вызов переданной тобою функции через указанное время.</p>
  <p>Итак, как и в случае с <code>setTimeout</code>(<a href="https://teletype.in/@java-script-stupid/X8ICeCrVY" target="_blank">лучше прочитай статью о setTimeout, будет намного понятнее</a>), <code>setInterval</code> принимает первым аргументом либо ссылку на функцию, либо функцию, а вторым аргументом передается время в миллисекундах, через которое переодически будет выполняться переданная функция:</p>
  <pre>function hello() {
   console.log(&#x27;Привет&#x27;);
}

setInterval(hello, 3000);

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

const intervalId = setInterval(hello, 3000);

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

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

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

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

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@java-script-stupid/X8ICeCrVY</guid><link>https://teletype.in/@java-script-stupid/X8ICeCrVY?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=java-script-stupid</link><comments>https://teletype.in/@java-script-stupid/X8ICeCrVY?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=java-script-stupid#comments</comments><dc:creator>java-script-stupid</dc:creator><title>Планирование вызова функции: setTimeout</title><pubDate>Thu, 02 Apr 2020 08:01:41 GMT</pubDate><media:content medium="image" url="https://teletype.in/files/32/5e/325e50ea-8160-4dce-87cc-c2236dd19198.png"></media:content><description><![CDATA[<img src="https://teletype.in/files/64/4d/644deafc-2744-4cfc-8c53-c8a71832c269.png"></img>Представь, что у тебя есть задача вывести приветственное сообщение пользователю через 5 секунд после того, как он перешел на страницу. Как это организовать средствами JavaScript?]]></description><content:encoded><![CDATA[
  <figure class="m_original">
    <img src="https://teletype.in/files/64/4d/644deafc-2744-4cfc-8c53-c8a71832c269.png" width="1920" />
  </figure>
  <p>Представь, что у тебя есть задача вывести приветственное сообщение пользователю через 5 секунд после того, как он перешел на страницу. Как это организовать средствами JavaScript?</p>
  <p>В этом вопросе нам поможет метод объекта <code>window</code> – <code>setTimeout()</code>. Этот метод запускает через указанное в аргументах время, указанную в аргументах функцию. Пример использования: </p>
  <pre>// 1-ый вариант использования
window.setTimeout(func, delay);

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

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

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

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

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

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@java-script-stupid/FSxPHRy1</guid><link>https://teletype.in/@java-script-stupid/FSxPHRy1?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=java-script-stupid</link><comments>https://teletype.in/@java-script-stupid/FSxPHRy1?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=java-script-stupid#comments</comments><dc:creator>java-script-stupid</dc:creator><title>Методы массивов: flat, fill</title><pubDate>Mon, 17 Feb 2020 14:06:09 GMT</pubDate><media:content medium="image" url="https://teletype.in/files/44/be/44be458e-2dab-4a0c-9079-2494b94f5357.png"></media:content><description><![CDATA[<img src="https://teletype.in/files/c8/42/c842462a-84ee-4b27-81e0-c5c7333b6fa8.png"></img>Данный метод появился недавно, но он очень крут. Он создает новый массив из всех подмассивов содержащихся в нем уменьшая мерность на указанное значение(по умолчанию 1). Наверное звучит очень сложно и запутанно и, скорее всего, прямо сейчас ты мало где сможешь применить данный метод на практике. Но пример все-равно давай посмотрим:]]></description><content:encoded><![CDATA[
  <figure class="m_original">
    <img src="https://teletype.in/files/c8/42/c842462a-84ee-4b27-81e0-c5c7333b6fa8.png" width="1920" />
  </figure>
  <h3>Метод flat</h3>
  <p>Данный метод появился недавно, но он очень крут. Он создает новый массив из всех подмассивов содержащихся в нем уменьшая мерность на указанное значение(по умолчанию 1). Наверное звучит очень сложно и запутанно и, скорее всего, прямо сейчас ты мало где сможешь применить данный метод на практике. Но пример все-равно давай посмотрим:</p>
  <pre>const arr = [1, 2, 3, [4, 5], [[7,8]]];
const transformArr = arr.flat();

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

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

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

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@java-script-stupid/R-LF464E</guid><link>https://teletype.in/@java-script-stupid/R-LF464E?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=java-script-stupid</link><comments>https://teletype.in/@java-script-stupid/R-LF464E?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=java-script-stupid#comments</comments><dc:creator>java-script-stupid</dc:creator><title>Методы массивов: Array.isArray, some, every</title><pubDate>Mon, 17 Feb 2020 14:01:50 GMT</pubDate><media:content medium="image" url="https://teletype.in/files/89/16/8916a4f3-9b1f-455e-814c-5bc05d08bb9c.png"></media:content><description><![CDATA[<img src="https://teletype.in/files/c1/80/c1803912-7e57-4693-b0d0-828ae4890cbf.png"></img>Порой требуется понять, являются ли данные, которые, например, пришли с сервера – массивом. Как мы можем это узнать? Существует оператор typeof, но в  JS нет отдельного типа для массивов. JS не различает массив от объекта: для него и то и другое – объекты. Но задачу как-то надо решать, именно для этого и существует статический метод isArray в объекте Array.]]></description><content:encoded><![CDATA[
  <figure class="m_original">
    <img src="https://teletype.in/files/c1/80/c1803912-7e57-4693-b0d0-828ae4890cbf.png" width="1920" />
  </figure>
  <h3>Метод Array.isArray</h3>
  <p>Порой требуется понять, являются ли данные, которые, например, пришли с сервера – массивом. Как мы можем это узнать? Существует оператор typeof, но в  JS нет отдельного типа для массивов. JS не различает массив от объекта: для него и то и другое – объекты. Но задачу как-то надо решать, именно для этого и существует статический метод <code>isArray</code> в объекте <code>Array</code>.</p>
  <pre>const obj = {name: &#x27;Толян&#x27;};
const arr = [1, 2, 3];

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

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

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

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

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

]]></content:encoded></item></channel></rss>