aboutsummaryrefslogtreecommitdiff
path: root/files/ru/learn/javascript
diff options
context:
space:
mode:
Diffstat (limited to 'files/ru/learn/javascript')
-rw-r--r--files/ru/learn/javascript/asynchronous/async_await/index.html411
-rw-r--r--files/ru/learn/javascript/asynchronous/concepts/index.html164
-rw-r--r--files/ru/learn/javascript/asynchronous/index.html59
-rw-r--r--files/ru/learn/javascript/asynchronous/introducing/index.html288
-rw-r--r--files/ru/learn/javascript/asynchronous/таймауты_и_интервалы/index.html638
-rw-r--r--files/ru/learn/javascript/building_blocks/build_your_own_function/index.html254
-rw-r--r--files/ru/learn/javascript/building_blocks/conditionals/index.html746
-rw-r--r--files/ru/learn/javascript/building_blocks/functions/index.html390
-rw-r--r--files/ru/learn/javascript/building_blocks/image_gallery/index.html146
-rw-r--r--files/ru/learn/javascript/building_blocks/index.html61
-rw-r--r--files/ru/learn/javascript/building_blocks/looping_code/index.html936
-rw-r--r--files/ru/learn/javascript/building_blocks/return_values/index.html172
-rw-r--r--files/ru/learn/javascript/building_blocks/test_your_skills_colon__functions/index.html99
-rw-r--r--files/ru/learn/javascript/building_blocks/события/index.html606
-rw-r--r--files/ru/learn/javascript/client-side_web_apis/client-side_storage/index.html794
-rw-r--r--files/ru/learn/javascript/client-side_web_apis/fetching_data/index.html379
-rw-r--r--files/ru/learn/javascript/client-side_web_apis/index.html53
-rw-r--r--files/ru/learn/javascript/client-side_web_apis/introduction/index.html277
-rw-r--r--files/ru/learn/javascript/client-side_web_apis/manipulating_documents/index.html321
-rw-r--r--files/ru/learn/javascript/client-side_web_apis/third_party_apis/index.html482
-rw-r--r--files/ru/learn/javascript/howto/index.html304
-rw-r--r--files/ru/learn/javascript/index.html64
-rw-r--r--files/ru/learn/javascript/объекты/adding_bouncing_balls_features/index.html212
-rw-r--r--files/ru/learn/javascript/объекты/index.html47
-rw-r--r--files/ru/learn/javascript/объекты/inheritance/index.html266
-rw-r--r--files/ru/learn/javascript/объекты/json/index.html353
-rw-r--r--files/ru/learn/javascript/объекты/object-oriented_js/index.html286
-rw-r--r--files/ru/learn/javascript/объекты/object_building_practice/index.html302
-rw-r--r--files/ru/learn/javascript/объекты/object_prototypes/index.html285
-rw-r--r--files/ru/learn/javascript/объекты/основы/index.html257
-rw-r--r--files/ru/learn/javascript/первые_шаги/a_first_splash/index.html675
-rw-r--r--files/ru/learn/javascript/первые_шаги/arrays/index.html678
-rw-r--r--files/ru/learn/javascript/первые_шаги/index.html56
-rw-r--r--files/ru/learn/javascript/первые_шаги/math/index.html423
-rw-r--r--files/ru/learn/javascript/первые_шаги/useful_string_methods/index.html723
-rw-r--r--files/ru/learn/javascript/первые_шаги/variables/index.html372
-rw-r--r--files/ru/learn/javascript/первые_шаги/what_is_javascript/index.html339
-rw-r--r--files/ru/learn/javascript/первые_шаги/создатель_глуых_историй/index.html148
-rw-r--r--files/ru/learn/javascript/первые_шаги/строки/index.html284
-rw-r--r--files/ru/learn/javascript/первые_шаги/что_пошло_не_так/index.html249
40 files changed, 13599 insertions, 0 deletions
diff --git a/files/ru/learn/javascript/asynchronous/async_await/index.html b/files/ru/learn/javascript/asynchronous/async_await/index.html
new file mode 100644
index 0000000000..751e08b45e
--- /dev/null
+++ b/files/ru/learn/javascript/asynchronous/async_await/index.html
@@ -0,0 +1,411 @@
+---
+title: Making asynchronous programming easier with async and await
+slug: Learn/JavaScript/Asynchronous/Async_await
+translation_of: Learn/JavaScript/Asynchronous/Async_await
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Promises", "Learn/JavaScript/Asynchronous/Choosing_the_right_approach", "Learn/JavaScript/Asynchronous")}}</div>
+
+<p class="summary">В ECMAScript версии 2017 появились <a href="/en-US/docs/Web/JavaScript/Reference/Statements/async_function">async functions</a> и ключевое слово <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/await">await</a></code> (<a href="/en-US/docs/Web/JavaScript/New_in_JavaScript/ECMAScript_Next_support_in_Mozilla">ECMAScript Next support in Mozilla</a>). По существу, такие функции есть синтаксический сахар над Promises и Generator functions (<a href="https://tc39.es/ecmascript-asyncawait/">ts39</a>). С их помощью легче писать/читать асинхронный код, ведь они позволяют использовать привычный синхронный стиль написания. В этой статье мы на базовом уровне разберемся в их устройстве.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Примечания:</th>
+ <td>Чтобы лучше понять материал, желательно перед чтением ознакомиться с основами JavaScript, асинхронными операциями вообще и объектами Promises.</td>
+ </tr>
+ <tr>
+ <th scope="row">Цель материала:</th>
+ <td>Научить писать современный асинхронный код с использованием Promises и async functions.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Основы_asyncawait">Основы async/await</h2>
+
+<h3 id="Ключевое_слово_async">Ключевое слово async</h3>
+
+<p>Ключевое слово async позволяет сделать из обычной функции (function declaration или function expression) асинхронную функцию (<a href="/en-US/docs/Web/JavaScript/Reference/Statements/async_function">async function</a>). Такая функция делает две вещи:<br>
+ - Оборачивает возвращаемое значение в Promise<br>
+ - Позволяет использовать ключевое слово await (см. дальше)</p>
+
+<p>Попробуйте выполнить в консоли браузера следующий код:</p>
+
+<pre class="brush: js notranslate">function hello() { return "Hello" };
+hello();</pre>
+
+<p>Функция возвращает "Hello" — ничего необычного, верно ?</p>
+
+<p>Но что если мы сделаем ее асинхронной ? Проверим:</p>
+
+<pre class="brush: js notranslate">async function hello() { return "Hello" };
+hello();</pre>
+
+<p>Как было сказано ранее, вызов асинхронной функции возвращает объект Promise.</p>
+
+<p>Вот пример с <a href="/en-US/docs/Web/JavaScript/Reference/Operators/async_function">async function expression</a>:</p>
+
+<pre class="brush: js notranslate">let hello = async function() { return "Hello" };
+hello();</pre>
+
+<p>Также можно использовать стрелочные функции:</p>
+
+<pre class="brush: js notranslate">let hello = async () =&gt; { return "Hello" };</pre>
+
+<p>Все они в общем случае делают одно и то же.</p>
+
+<p>Чтобы получить значение, которое возвращает Promise, мы как обычно можем использовать метод <code>.then()</code>:</p>
+
+<pre class="brush: js notranslate">hello().then((value) =&gt; console.log(value))</pre>
+
+<p>или еще короче</p>
+
+<pre class="brush: js notranslate">hello().then(console.log)
+</pre>
+
+<p>Итак, ключевое слово <code>async</code>, превращает обычную функцию в асинхронную и результат вызова функции оборачивает в Promise. Также асинхронная функция позволяет использовать в своем теле ключевое слово await, о котором далее.</p>
+
+<h3 id="Ключевое_слово_await">Ключевое слово await</h3>
+
+<p>Асинхронные функции становятся по настоящему мощными, когда вы используете ключевое слово <a href="/en-US/docs/Web/JavaScript/Reference/Operators/await">await</a>  — по факту, <strong><code>await</code> работает только в асинхронных функциях</strong>. Мы можем использовать await перед promise-based функцией, чтобы остановить поток выполнения и дождаться результата ее выполнения (результат Promise). В то же время, остальной код нашего приложения не блокируется и продолжает работать.</p>
+
+<p>Вы можете использовать <code>await</code> перед любой функцией, что возвращает Promise, включая Browser API функции.</p>
+
+<p>Небольшой пример:</p>
+
+<pre class="brush: js notranslate">async function hello() {
+ return greeting = await Promise.resolve("Hello");
+};
+
+hello().then(alert);</pre>
+
+<p>Конечно, на практике код выше бесполезен, но в учебных целях он иллюстрирует синтаксис асинхронных функций. Теперь давайте перейдем к реальным примерам.</p>
+
+<h2 id="Переписываем_Promises_с_ипользованием_asyncawait">Переписываем Promises с ипользованием async/await</h2>
+
+<p>Давайте посмотрим на пример из предыдущей статьи:</p>
+
+<pre class="brush: js notranslate">fetch('coffee.jpg')
+.then(response =&gt; {
+  if (!response.ok) {
+    throw new Error(`HTTP error! status: ${response.status}`);
+  } else {
+    return response.blob();
+  }
+})
+.then(myBlob =&gt; {
+ let objectURL = URL.createObjectURL(myBlob);
+ let image = document.createElement('img');
+ image.src = objectURL;
+ document.body.appendChild(image);
+})
+.catch(e =&gt; {
+ console.log('There has been a problem with your fetch operation: ' + e.message);
+});</pre>
+
+<p>К этому моменту вы должны понимать как работают Promises, чтобы понять все остальное. Давайте перепишем код используя async/await и оценим разницу.</p>
+
+<pre class="brush: js notranslate">async function myFetch() {
+ let response = await fetch('coffee.jpg');
+
+ if (!response.ok) {
+ throw new Error(`HTTP error! status: ${response.status}`);
+ } else {
+ let myBlob = await response.blob();
+
+ let objectURL = URL.createObjectURL(myBlob);
+ let image = document.createElement('img');
+ image.src = objectURL;
+ document.body.appendChild(image);
+ }
+}
+
+myFetch()
+.catch(e =&gt; {
+ console.log('There has been a problem with your fetch operation: ' + e.message);
+});</pre>
+
+<p>Согласитесь, что код стал короче и понятнее — больше никаких блоков <code>.then()</code> по всему скрипту!</p>
+
+<p>Так как ключевое слово <code>async</code> заставляет функцию вернуть Promise, мы можем использовать гибридный подход:</p>
+
+<pre class="brush: js notranslate">async function myFetch() {
+ let response = await fetch('coffee.jpg');
+ if (!response.ok) {
+    throw new Error(`HTTP error! status: ${response.status}`);
+  } else {
+    return await response.blob();
+  }
+}
+
+myFetch().then((blob) =&gt; {
+ let objectURL = URL.createObjectURL(blob);
+ let image = document.createElement('img');
+ image.src = objectURL;
+ document.body.appendChild(image);
+}).catch(e =&gt; console.log(e));</pre>
+
+<p>Можете попрактиковаться самостоятельно, или запустить наш <a href="https://mdn.github.io/learning-area/javascript/asynchronous/async-await/simple-fetch-async-await.html">live example</a> (а также <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/async-await/simple-fetch-async-await.html">source code</a>).</p>
+
+<h3 id="Минуточку_а_как_это_все_работает">Минуточку, а как это все работает ?</h3>
+
+<p>Вы могли заметить, что мы обернули наш код в функцию и сделали ее асинхронной с помощью acync. Это было обязательно - нам надо создать контейнер, внутри которого будет запускаться асинхронный код и будет возмоность дождаться его результата с помощью await, не блокируя остальной код нашег скрипта.</p>
+
+<p>Внутри <code>myFetch()</code> находится код, который слегка напоминает версию на Promise, но есть важные отличия. Вместо того, чтобы писать цепочку блоков <code>.then()</code> мы просто использует ключевое слово <code>await</code> перед вызовом promise-based функции и присваиваем результат в переменную. Ключеовое слово <code>await</code> говорит JavaScript runtime приостановить код в этой строке, не блокируя остальной код скприта за пределами асинхронной функции. Когда вызов promise-based функции будет готов вернуть результат, выполнение продолжится с этой строки дальше.<br>
+ <br>
+ Пример:</p>
+
+<pre class="brush: js notranslate">let response = await fetch('coffee.jpg');</pre>
+
+<p>Значение Promise, которое вернет <code>fetch()</code> будет присвоено переменной <code>response</code> только тогда, когда оно будет доступно - парсер делает паузу на данной строке дожидаясь этого момента. Как только значение доступно, парсер переходит к следующей строке, в которой создается объект <code><a href="/en-US/docs/Web/API/Blob">Blob</a></code> из результата Promise. В этой строке, кстати, также используется <code>await</code>, потому что метод <code>.blob()</code> также возвращет Promise. Когда результат готов, мы возвращаем его наружу из <code>myFetch()</code>.</p>
+
+<p>Обратите внимание, когда мы вызываем <code>myFetch()</code>, она возвращает Promise, поэтому мы можем вызвать <code>.then()</code> на результате, чтобы отобразить его на экране.<br>
+ <br>
+ К этому моменту вы наверное думаете "Это реально круто!", и вы правы - чем меньше блоков <code>.then()</code>, тем легче читать код.</p>
+
+<h3 id="Добавляем_обработку_ошибок">Добавляем обработку ошибок</h3>
+
+<p><br>
+ Чтобы обработать ошибки у нас есть несколько вариантов</p>
+
+<p>Мы можем использовать синхронную <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/try...catch">try...catch</a></code> структуру с <code>async</code>/<code>await</code>. Вот измененная версия первого примера выше:</p>
+
+<pre class="brush: js notranslate">async function myFetch() {
+ try {
+ let response = await fetch('coffee.jpg');
+
+ if (!response.ok) {
+  throw new Error(`HTTP error! status: ${response.status}`);
+ } else {
+  let myBlob = await response.blob();
+  let objectURL = URL.createObjectURL(myBlob);
+  let image = document.createElement('img');
+  image.src = objectURL;
+  document.body.appendChild(image);
+ }
+ } catch(e) {
+ console.log(e);
+ }
+}
+
+myFetch();</pre>
+
+<p>В блок <code>catch() {}</code> передается объект ошибки, который мы назвали <code>e</code>; мы можем вывести его в консоль, чтобы посмотреть детали: где и почему возникла ошибка.</p>
+
+<p>Если вы хотите использовать гибридный подходы (пример выше), лучше использовать блок <code>.catch()</code> после блока <code>.then()</code> вот так:</p>
+
+<pre class="brush: js notranslate">async function myFetch() {
+ let response = await fetch('coffee.jpg');
+ if (!response.ok) {
+  throw new Error(`HTTP error! status: ${response.status}`);
+ } else {
+  return await response.blob();
+ }
+}
+
+myFetch().then((blob) =&gt; {
+ let objectURL = URL.createObjectURL(blob);
+ let image = document.createElement('img');
+ image.src = objectURL;
+ document.body.appendChild(image);
+})
+.catch((e) =&gt;
+ console.log(e)
+);</pre>
+
+<p>Так лучше, потому что блок <code>.catch()</code> словит ошибки как из асинхронной функции, так и из Promise. Если бы мы использовали блок <code>try</code>/<code>catch</code>, мы бы не словили ошибку, которая произошла в самой <code>myFetch()</code> функции.</p>
+
+<p>Вы можете посмотреть оба примера на GitHub:</p>
+
+<ul>
+ <li><a href="https://mdn.github.io/learning-area/javascript/asynchronous/async-await/simple-fetch-async-await-try-catch.html">simple-fetch-async-await-try-catch.html</a> (смотреть <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/async-await/simple-fetch-async-await-try-catch.html">source code</a>)</li>
+ <li><a href="https://mdn.github.io/learning-area/javascript/asynchronous/async-await/simple-fetch-async-await-promise-catch.html">simple-fetch-async-await-promise-catch.html</a> (смотреть <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/async-await/simple-fetch-async-await-promise-catch.html">source code</a>)</li>
+</ul>
+
+<h2 id="Await_и_Promise.all">Await и Promise.all()</h2>
+
+<p>Как вы помните, асинхронные функции построены поверх <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">promises</a>, поэтому они совместимы со всеми возможностями последних. Мы легко можем подождать выполнение <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all">Promise.all()</a></code>, присвоить результат в переменную и все это сделать используя синхронный стиль. Опять, вернемся к <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/promises/promise-all.html">an example we saw in our previous article</a>. Откройте пример в соседней вкладке, чтобы лучше понять разницу.</p>
+
+<p>Версия с async/await (смотрите <a href="https://mdn.github.io/learning-area/javascript/asynchronous/async-await/promise-all-async-await.html">live demo</a> и <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/async-await/promise-all-async-await.html">source code</a>), сейчас выглядит так:</p>
+
+<pre class="brush: js notranslate">async function fetchAndDecode(url, type) {
+ let response = await fetch(url);
+
+ let content;
+
+ if (!response.ok) {
+ throw new Error(`HTTP error! status: ${response.status}`);
+ } else {
+ if(type === 'blob') {
+ content = await response.blob();
+ } else if(type === 'text') {
+ content = await response.text();
+ }
+
+ return content;
+ }
+
+}
+
+async function displayContent() {
+ let coffee = fetchAndDecode('coffee.jpg', 'blob');
+ let tea = fetchAndDecode('tea.jpg', 'blob');
+ let description = fetchAndDecode('description.txt', 'text');
+
+ let values = await Promise.all([coffee, tea, description]);
+
+ let objectURL1 = URL.createObjectURL(values[0]);
+ let objectURL2 = URL.createObjectURL(values[1]);
+ let descText = values[2];
+
+ let image1 = document.createElement('img');
+ let image2 = document.createElement('img');
+ image1.src = objectURL1;
+ image2.src = objectURL2;
+ document.body.appendChild(image1);
+ document.body.appendChild(image2);
+
+ let para = document.createElement('p');
+ para.textContent = descText;
+ document.body.appendChild(para);
+}
+
+displayContent()
+.catch((e) =&gt;
+ console.log(e)
+);</pre>
+
+<p>Вы видите, что мы легко изменили <code>fetchAndDecode()</code> функцию в асинхронный вариант. Взгляните на строку с <code>Promise.all()</code>:</p>
+
+<pre class="brush: js notranslate">let values = await Promise.all([coffee, tea, description]);</pre>
+
+<p>С помощью <code>await</code> мы ждем массив результатов всех трех Promises и присваиваем его в переменную <code>values</code>. Это асинхронный код, но он написан в синхронном стиле, за счет чего он гораздо читабельнее.<br>
+ <br>
+ Мы должны обернуть весь код в синхронную функцию, <code>displayContent()</code>, и мы не сильно сэкономили на количестве кода, но мы извлекли код блока <code>.then()</code>, за счет чего наш код стал гораздо чище.</p>
+
+<p>Для обработки ошибок мы добавили блок <code>.catch()</code> для функции <code>displayContent()</code>; Это позволило нам отловить ошибки в обоих функциях.</p>
+
+<div class="blockIndicator note">
+<p><strong>Заметка</strong>: Мы также можем использовать синхронный блок <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/try...catch#The_finally_clause">finally</a></code> внутри асинхронной функции, вместо асинхронного <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/try...catch#The_finally_clause">.finally</a>()</code>, чтобы получить информацию о результате нашей операции — смотрите в действии в нашем <a href="https://mdn.github.io/learning-area/javascript/asynchronous/async-await/promise-finally-async-await.html">live example</a> (смотрите <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/async-await/promise-finally-async-await.html">source code</a>).</p>
+</div>
+
+<h2 id="Недостатки_asyncawait">Недостатки async/await</h2>
+
+<p>Асинхронные функции с async/await бывают очень удобными, но есть несколько замечаний, о которых полезно знать.</p>
+
+<p>Async/await позволяет вам писать код в синхронном стиле. Ключевое слово <code>await</code> блокирует приостанавливает выполнение ptomise-based функции до того момента, пока promise примет статуc fulfilled. Это не блокирует код за пределами вашей асинхронной функции, тем не менее важно помнить, что внутри асинхронной функции поток выполнения блокируется.<br>
+ <br>
+ Ваш код может стать медленнее за счет большого количества awaited promises, которые идут один за другим. Каждый <code>await</code> должен дождаться выполнения предыдущего, тогда как на самом деле мы хотим, чтобы наши Promises выполнялись одновременно, как если бы мы не использовали async/await.<br>
+ <br>
+ Есть подход, который позволяет обойти эту проблему - сохранить все выполняющиеся Promises в переменные, а уже после этого дожидаться (awaiting) их результата. Давайте посмотрим на несколько примеров.</p>
+
+<p>We've got two examples available — <a href="https://mdn.github.io/learning-area/javascript/asynchronous/async-await/slow-async-await.html">slow-async-await.html</a> (see <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/async-await/slow-async-await.html">source code</a>) and <a href="https://mdn.github.io/learning-area/javascript/asynchronous/async-await/fast-async-await.html">fast-async-await.html</a> (see <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/async-await/fast-async-await.html">source code</a>). Both of them start off with a custom promise function that fakes an async process with a <code><a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout">setTimeout()</a></code> call:</p>
+
+<pre class="brush: js notranslate">function timeoutPromise(interval) {
+ return new Promise((resolve, reject) =&gt; {
+ setTimeout(function(){
+ resolve("done");
+ }, interval);
+ });
+};</pre>
+
+<p>Then each one includes a <code>timeTest()</code> async function that awaits three <code>timeoutPromise()</code> calls:</p>
+
+<pre class="brush: js notranslate">async function timeTest() {
+ ...
+}</pre>
+
+<p>Each one ends by recording a start time, seeing how long the <code>timeTest()</code> promise takes to fulfill, then recording an end time and reporting how long the operation took in total:</p>
+
+<pre class="brush: js notranslate">let startTime = Date.now();
+timeTest().then(() =&gt; {
+ let finishTime = Date.now();
+ let timeTaken = finishTime - startTime;
+ alert("Time taken in milliseconds: " + timeTaken);
+})</pre>
+
+<p>It is the <code>timeTest()</code> function that differs in each case.</p>
+
+<p>In the <code>slow-async-await.html</code> example, <code>timeTest()</code> looks like this:</p>
+
+<pre class="brush: js notranslate">async function timeTest() {
+ await timeoutPromise(3000);
+ await timeoutPromise(3000);
+ await timeoutPromise(3000);
+}</pre>
+
+<p>Here we simply await all three <code>timeoutPromise()</code> calls directly, making each one alert for 3 seconds. Each subsequent one is forced to wait until the last one finished — if you run the first example, you'll see the alert box reporting a total run time of around 9 seconds.</p>
+
+<p>In the <code>fast-async-await.html</code> example, <code>timeTest()</code> looks like this:</p>
+
+<pre class="brush: js notranslate">async function timeTest() {
+ const timeoutPromise1 = timeoutPromise(3000);
+ const timeoutPromise2 = timeoutPromise(3000);
+ const timeoutPromise3 = timeoutPromise(3000);
+
+ await timeoutPromise1;
+ await timeoutPromise2;
+ await timeoutPromise3;
+}</pre>
+
+<p>Here we store the three <code>Promise</code> objects in variables, which has the effect of setting off their associated processes all running simultaneously.</p>
+
+<p>Next, we await their results — because the promises all started processing at essentially the same time, the promises will all fulfill at the same time; when you run the second example, you'll see the alert box reporting a total run time of just over 3 seconds!</p>
+
+<p>You'll have to test your code carefully, and bear this in mind if performance starts to suffer.</p>
+
+<p>Another minor inconvenience is that you have to wrap your awaited promises inside an async function.</p>
+
+<h2 id="Asyncawait_class_methods">Async/await class methods</h2>
+
+<p>As a final note before we move on, you can even add <code>async</code> in front of class/object methods to make them return promises, and <code>await</code> promises inside them. Take a look at the <a href="/en-US/docs/Learn/JavaScript/Objects/Inheritance#ECMAScript_2015_Classes">ES class code we saw in our object-oriented JavaScript article</a>, and then look at our modified version with an <code>async</code> method:</p>
+
+<pre class="brush: js notranslate">class Person {
+ constructor(first, last, age, gender, interests) {
+ this.name = {
+ first,
+ last
+ };
+ this.age = age;
+ this.gender = gender;
+ this.interests = interests;
+ }
+
+ async greeting() {
+ return await Promise.resolve(`Hi! I'm ${this.name.first}`);
+ };
+
+ farewell() {
+ console.log(`${this.name.first} has left the building. Bye for now!`);
+ };
+}
+
+let han = new Person('Han', 'Solo', 25, 'male', ['Smuggling']);</pre>
+
+<p>The first class method could now be used something like this:</p>
+
+<pre class="brush: js notranslate">han.greeting().then(console.log);</pre>
+
+<h2 id="Browser_support">Browser support</h2>
+
+<p>One consideration when deciding whether to use async/await is support for older browsers. They are available in modern versions of most browsers, the same as promises; the main support problems come with Internet Explorer and Opera Mini.</p>
+
+<p>If you want to use async/await but are concerned about older browser support, you could consider using the <a href="https://babeljs.io/">BabelJS</a> library — this allows you to write your applications using the latest JavaScript and let Babel figure out what changes if any are needed for your user’s browsers. On encountering a browser that does not support async/await, Babel's polyfill can automatically provide fallbacks that work in older browsers.</p>
+
+<h2 id="Conclusion">Conclusion</h2>
+
+<p>And there you have it — async/await provide a nice, simplified way to write async code that is simpler to read and maintain. Even with browser support being more limited than other async code mechanisms at the time of writing, it is well worth learning and considering for use, both for now and in the future.</p>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Promises", "Learn/JavaScript/Asynchronous/Choosing_the_right_approach", "Learn/JavaScript/Asynchronous")}}</p>
+
+<h2 id="In_this_module">In this module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Concepts">General asynchronous programming concepts</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Introducing">Introducing asynchronous JavaScript</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Timeouts_and_intervals">Cooperative asynchronous JavaScript: Timeouts and intervals</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Promises">Graceful asynchronous programming with Promises</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Async_await">Making asynchronous programming easier with async and await</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Choosing_the_right_approach">Choosing the right approach</a></li>
+</ul>
diff --git a/files/ru/learn/javascript/asynchronous/concepts/index.html b/files/ru/learn/javascript/asynchronous/concepts/index.html
new file mode 100644
index 0000000000..b82d4d4a51
--- /dev/null
+++ b/files/ru/learn/javascript/asynchronous/concepts/index.html
@@ -0,0 +1,164 @@
+---
+title: Основные понятия асинхронного программирования
+slug: Learn/JavaScript/Asynchronous/Concepts
+tags:
+ - JavaScript
+ - Promises
+ - Асинхронность
+ - Обучение
+ - блокировки
+ - потоки
+translation_of: Learn/JavaScript/Asynchronous/Concepts
+---
+<div>{{LearnSidebar}}{{NextMenu("Learn/JavaScript/Asynchronous/Introducing", "Learn/JavaScript/Asynchronous")}}</div>
+
+<p>В этой статье мы бегло познакомимся с основными понятиями, связанными с асинхронным программированием и как они применяются в веб браузерах и  JavaScript. Вы должны понять эти концепции, прежде чем приступать к другим статьям этого раздела.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Необходимые знания:</th>
+ <td>Базовая компьютерная грамотность, знакомство с основами JavaScript.</td>
+ </tr>
+ <tr>
+ <th scope="row">Цель:</th>
+ <td><span class="tlid-translation translation" lang="ru"><span title="">Понять основные идеи асинхронного программирования, и как они проявляются в веб-браузерах и JavaScript.</span></span></td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Что_же_такое_Асинхронность">Что же такое Асинхронность?</h2>
+
+<p>Как правило, программный код выполняется последовательно, только одна конкретная операция происходит в данный момент времени. Если функция зависит от результата выполнения другой функции, то она должна дождаться пока нужная ей функция не завершит свою работу и не вернет результат и до тех пор пока это не произойдет, выполнение программы, по сути, будет остановлено с точки зрения пользователя.</p>
+
+<p>Пользователь современного ПК, наверняка, наблюдал, как курсор меняет свой вид и становится "разноцветным спинером" (у пользователей MacOS). Таким образом операционная система сообщает - "текущая программа, ожидает завершения какого то длительного процесса в системе и я решила сообщить тебе, что бы ты не волновался".</p>
+
+<p><img alt="Multi-colored macOS beachball busy spinner" src="https://mdn.mozillademos.org/files/16577/beachball.jpg" style="display: block; float: left; height: 256px; margin: 0px 30px 0px 0px; width: 250px;"></p>
+
+<p>Такое поведение удручает и говорит о неправильном использовании процессорного времени, к тому же современные компьютеры имеют процессоры с несколькими ядрами. Не нужно ничего ждать, вы можете передать следующую задачу свободному ядру процессора и когда она завершится, то сообщит вам об этом. Такой подход позволяет выполнять разные задачи одновременно, в этом и заключается задача асинхронности в программировании. Программная среда, которую вы используете (браузер в случае веб разработки), должна иметь возможность выполнять различного рода задачи ассинхронно.</p>
+
+<h2 id="Блокировка_кода">Блокировка кода</h2>
+
+<p>Асинхронные техники очень полезны, особенно при веб разработке. Когда ваше приложение запущено в браузере и выполняет свои задачи, не возвращая контроль окружению, браузер может подвисать. Это называется <strong>блокировка</strong>; браузер заблокирован и не может реагировать на действия пользователя и выполнять служебные.задачи, до тех пор пока веб приложение не освободит ресурсы процессора.</p>
+
+<p>Давайте рассмотрим несколько примеров, которые покажут, что именно значит <strong>блокировка</strong>.</p>
+
+<p>В нашем <a href="https://github.com/mdn/learning-area/tree/master/javascript/asynchronous/introducing">simple-sync.html</a> примере (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/introducing/simple-sync.html">see it running live</a>), добавим кнопке событие на клик, чтобы при нажатии на нее запускалась трудоемкая операция (рассчет 10000000 дат, и вывод последнейрассчитаной даты на консоль) после чего в DOM добавляется еще один параграф:</p>
+
+<pre class="brush: js notranslate">const btn = document.querySelector('button');
+btn.addEventListener('click', () =&gt; {
+ let myDate;
+ for(let i = 0; i &lt; 10000000; i++) {
+ let date = new Date();
+ myDate = date
+ }
+
+ console.log(myDate);
+
+ let pElem = document.createElement('p');
+ pElem.textContent = 'This is a newly-added paragraph.';
+ document.body.appendChild(pElem);
+});</pre>
+
+<p>Когда запустите этот пример, откройте JavaScript консоль и нажмите на кнопку — вы заметите, что параграф не появится на странице, до тех пор пока все даты не будут рассчитаны и результат последнего вычисления не будет выведен на консоль. Этот код выполняется в том порядке, в котором он написан в файле и самая последняя операция не будет запущена, пока не завершатся все операции перед ней.</p>
+
+<div class="blockIndicator note">
+<p><strong>Примечание</strong>: Предыдущий пример слишком не реальный. Вам никогда не понадобится считать столько дат в реальном приложении! Однако, он помогает вам понять основную идею.</p>
+</div>
+
+<p>В нашем следующем примере, <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/introducing/simple-sync-ui-blocking.html">simple-sync-ui-blocking.html</a> (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/introducing/simple-sync-ui-blocking.html">посмотреть пример</a>), мы сделаем что-нибудь более реалистичное, с чем вы сможете столкнуться на реальной странице. Мы заблокируем действия пользователя отрисовкой страницы. В этом примере у нас две кнопки:</p>
+
+<ul>
+ <li>Кнопка "Fill canvas", если на нее кликнуть, рисует в элементе
+ <div>{{htmlelement("canvas")}}</div>
+ миллион синих кругов.</li>
+ <li>Кнопка "Click me for alert", при нажатии показывает предупреждение.</li>
+</ul>
+
+<pre class="brush: js notranslate">function expensiveOperation() {
+ for(let i = 0; i &lt; 1000000; i++) {
+ ctx.fillStyle = 'rgba(0,0,255, 0.2)';
+ ctx.beginPath();
+ ctx.arc(random(0, canvas.width), random(0, canvas.height), 10, degToRad(0), degToRad(360), false);
+ ctx.fill()
+ }
+}
+
+fillBtn.addEventListener('click', expensiveOperation);
+
+alertBtn.addEventListener('click', () =&gt;
+ alert('You clicked me!')
+);</pre>
+
+<p>Если вы быстро нажмете на первую кнопку и затем быстро кликните на вторую, вы увидите, что предупреждение не появится на странице, пока все круги не будут отрисованы. Первая операция блокирует выполнение следующей до тех пор пока не завершится сама.</p>
+
+<div class="blockIndicator note">
+<p><strong>Примечание</strong>: Хорошо, в приведенном некрасивом примере, мы получили эффект блокировки, который показывает общую проблему  при разработке приложений, с которой все время приходится бороться разработчикам.</p>
+</div>
+
+<p>Почему так происходит? Потому что JavaScript, в общем случае, выполняет команды в <strong>одном потоке</strong>. Пришло время познакомиться с понятием <strong>потока</strong>.</p>
+
+<h2 id="Потоки">Потоки</h2>
+
+<p>Под <strong>потоком,</strong> обычно, понимают одиночный процесс, который может использовать программа, для выполнения своих нужд. Каждый поток может выполнять только одну в текущий момент времени:</p>
+
+<pre class="notranslate">Task A --&gt; Task B --&gt; Task C</pre>
+
+<p>Каждая задача будет выполнена последовательно; только когда текущая задача завершится, следующая сможет начаться.</p>
+
+<p>Как мы говорили выше, большинство компьютеров теперь имеют процессор с несколькими ядрами, т.е. могут выполнять несколько задач одновременно. Языки программирования, поддерживающие многопоточность, могут использовать несколько ядер, чтобы выпонять несколько задач одновременно:</p>
+
+<pre class="notranslate">Thread 1: Task A --&gt; Task B
+Thread 2: Task C --&gt; Task D</pre>
+
+<h3 id="JavaScript_однопоточный">JavaScript однопоточный</h3>
+
+<p>JavaScript, традиционно для скриптовых языков, однопоточный. Даже, если есть несколько ядер, вы можете использовать их только для выполнения задач в одном потоке, называемом <strong>основной поток</strong>. Наш пример выше, выполняется следующим образом:</p>
+
+<pre class="notranslate">Main thread: Render circles to canvas --&gt; Display alert()</pre>
+
+<p>В итоге, JavaScript получил несколько инструментов, которые могут помочь в решении подобных проблем. <a href="/en-US/docs/Web/API/Web_Workers_API">Web workers</a> позволяют вам обработать некоторый JavaScript код в отдельном потоке, который называется обработчик, таким образом вы можете запускать отдельные блоки JavaScript кода одновременно. В основном, вы будете использовать воркеры, чтобы запустить ресурсоемкий процесс, отдельно от основного потока, чтобы не блокировать действия пользователя.</p>
+
+<pre class="notranslate"> Main thread: Task A --&gt; Task C
+Worker thread: Expensive task B</pre>
+
+<p>Помня об этом, выполните наш следующий пример <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/introducing/simple-sync-worker.html">simple-sync-worker.html</a> (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/introducing/simple-sync-worker.html">посмотреть пример в действии</a>), с открытой консолью. Это переписанный предыдущий пример, который теперь рассчитывает 10 миллионов дат в отдельном потоке обработчика. Теперь, когда вы нажимаете на кнопку, браузер может добавить новый элемент на страницу, до того как все даты будут посчитаны. Самая первая операция больше не блокирует выполнение следующей.</p>
+
+<h2 id="Асинхронный_код">Асинхронный код</h2>
+
+<p>Воркеры полезный инструмент, но у них есть свои ограничения. Самое существенное, заключается в том, что они не имеют доступа к {{Glossary("DOM")}} — вы не можете использовать воркер для обновления UI. Мы не можем отрисовать миллион наших точек  внутри воркера; он может только обработать большой объем информации.</p>
+
+<p>Следующая проблема заключается в том, что даже если код запущенный в воркере ничего не блокирует, он в целом остается синхронным. Это проблема появляется, когда какой-то функции требуются результаты выполнения нескольких предыдущих функций. Рассмотрим следующую диаграмму потоков:</p>
+
+<pre class="notranslate">Main thread: Task A --&gt; Task B</pre>
+
+<p>В этом примере, предположим Task A делает что-то вроде получения картинки с сервера а Task B затем делает что-нибудь с полученной картинкой, например, применяет к ней фильтр. Если запустить выполняться Task A и тут же попытаться выполнить Task B, то вы получите ошибку, поскольку картинка еще не будет доступна.</p>
+
+<pre class="notranslate"> Main thread: Task A --&gt; Task B --&gt; |Task D|
+Worker thread: Task C -----------&gt; | |</pre>
+
+<p>Теперь, давайте предположим, что Task D использует результат выполнения обеих задач Task B и Task C. Если мы уверенны, что оба результата будут доступны одновременно, тогда не возникнет проблем, однако, часто это не так. Если Task D попытаться запустить, когда какого-то нужного ей результата еще нет, выполнение закончится ошибкой.</p>
+
+<p>Чтобы избежать подобных проблем, браузеры позволяют нам выполнять определенные операции асинхронно. Такие возможности, как <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promises</a> позволяют запустить некоторую операцию (например, получение картинки с сервера), и затем подождать пока операция не вернет результат, перед тем как начать выполнение другой задачи:</p>
+
+<pre class="notranslate">Main thread: Task A Task B
+ Promise: |__async operation__|</pre>
+
+<p>Поскольку операция выполняется где-то отдельно, основной поток не блокируется, при выполнении асинхронных задач.</p>
+
+<p>В следующей статье, мы покажем вам, как писать асинхронный код. Захватывает дух, неправда ли? Продолжайте читать!</p>
+
+<h2 id="Заключение">Заключение</h2>
+
+<p>При проектировании современных программ все больше используется асинхронное программирование, чтобы программа имела возможность выполнять несколько операций в конкретный момент времени. Как только вы начнете использовать новые, более мощные возможности API, вы обнаружите множество ситуаций, где решить нужную задачу можно только асинхронно. Раньше было сложно писать асинхронный код. До сих пор, нужно время, чтобы привыкнуть к такому подходу, но процесс стал намного легче. Далее, в этом разделе, мы будем глубже исследовать вопрос, когда же асинхронный код необходим и как спроектировать программу, чтобы избежать проблем, описанных выше.</p>
+
+<h2 id="В_этом_модуле">В этом модуле</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Concepts">General asynchronous programming concepts</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Introducing">Introducing asynchronous JavaScript</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Timeouts_and_intervals">Cooperative asynchronous JavaScript: Timeouts and intervals</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Promises">Graceful asynchronous programming with Promises</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Async_await">Making asynchronous programming easier with async and await</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Choosing_the_right_approach">Choosing the right approach</a></li>
+</ul>
diff --git a/files/ru/learn/javascript/asynchronous/index.html b/files/ru/learn/javascript/asynchronous/index.html
new file mode 100644
index 0000000000..19d66b114c
--- /dev/null
+++ b/files/ru/learn/javascript/asynchronous/index.html
@@ -0,0 +1,59 @@
+---
+title: Асинхронный JavaScript
+slug: Learn/JavaScript/Asynchronous
+tags:
+ - Beginner
+ - CodingScripting
+ - Guide
+ - JavaScript
+ - Landing
+ - Promises
+ - async
+ - asynchronous
+ - await
+ - callbacks
+ - requestAnimationFrame
+ - setInterval
+ - setTimeout
+ - Асинхронность
+ - асинхронное программирование
+translation_of: Learn/JavaScript/Asynchronous
+---
+<div>{{LearnSidebar}}</div>
+
+<p class="summary"><span class="seoSummary">В этом модуле мы рассмотрим {{Glossary("asynchronous")}} {{Glossary("JavaScript")}}, почему это важно, и как это поможет эффективно справляться с потенциальной блокировкой операций, таких как получение ресурсов с сервера или запись в файл.</span></p>
+
+<h2 id="Необходимые_знания">Необходимые знания</h2>
+
+<p>Асинхронный JavaScript довольно сложная тема, и мы советуем пройти <a href="/ru/docs/Learn/JavaScript/First_steps">Первые шаги в JavaScript</a> и <a href="/ru/docs/Learn/JavaScript/Building_blocks">Блоки в JavaScript</a> прежде чем начать эту тему.</p>
+
+<p>Если вы ещё не знакомы с концепциями асинхронного программирования, вам стоит начать со статьи <a href="/ru/docs/Learn/JavaScript/Asynchronous/Concepts">Основные концепции асинхронного программирования</a> в этом модуле. А если уже знакомы, то можете сразу переходить к статье <a href="/ru/docs/Learn/JavaScript/Asynchronous/Introducing">Введение в асинхронный JavaScript</a>.</p>
+
+<div class="note">
+<p><strong>Заметка</strong>: Если вы работаете за компьютером/планшетом/другим устройством где у вас нет возможности создавать собственные файлы, вы можете попробовать(почти все) примеры кода в одном из веб-приложений, таких, как <a href="http://jsbin.com/">JSBin</a> или <a href="https://thimble.mozilla.org/">Thimble</a>.</p>
+</div>
+
+<h2 id="Руководства">Руководства</h2>
+
+<dl>
+ <dt><a href="/ru/docs/Learn/JavaScript/Asynchronous/Concepts">Основные концепции асинхронного программирования</a></dt>
+ <dd>
+ <p>В этой статье мы пройдёмся по нескольким важным концепциям касающихся асинхронного программирования, и того как это выглядит в браузерах и JavaScript. Вы должны усвоить эти концепции прежде чем изучать другие статьи в этом модуле.</p>
+ </dd>
+ <dt><a href="/ru/docs/Learn/JavaScript/Asynchronous/Introducing">Введение в асинхронный JavaScript</a></dt>
+ <dd>В этой статье мы кратко расскажем о проблемах связанных с синхронным JavaScript-ом, и взглянем на различные техники асинхронного программирования с которыми вы столкнётесь, покажем вам как эти техники помогают решать проблемы синхронного JavaScript.</dd>
+ <dt><a href="/ru/docs/Learn/JavaScript/Asynchronous/Loops_and_intervals">Кооперативная асинхронность в JavaScript: Таймауты и интервалы</a></dt>
+ <dd>Здесь мы рассматриваем традиционные методы JavaScript, которые позволяют запускать код асинхронно по истечению заданного времени, или с регулярным интервалом (например: заданное количество раз в секунду), обсудим их пользу, а так же их неотъемлемые проблемы.</dd>
+ <dt><a href="/ru/docs/Learn/JavaScript/Asynchronous/Promises">Изящная обработка асинхронных операций с Промисами</a></dt>
+ <dd>Промисы это достаточно новая функция в языке JavaScript, которая позволяет вам откладывать дальнейшие операции, пока предыдущая не выполнится, или реагировать на её неудачное выполнение. Это очень полезно, для установки нужной последовательности операций для корректной работы. Эта статья показывает как работают промисы, и вы рассмотрите то, как они работают в WebAPIs, и узнаете как писать свои собственные.</dd>
+ <dt><a href="/ru/docs/Learn/JavaScript/Asynchronous/Async_await">Делаем асинхронное программирование проще с async и await</a></dt>
+ <dd>Промисы могут быть достаточно сложными для написания и понимания, поэтому современные браузеры ввели функцию <code>async</code> и оператор <code>await</code> — где первый позволяет стандартным функциям неявно асинхронно работать с промисами, а последний может использоваться внутри <code>async</code> функций, для ожидания промиса, прежде чем функция продолжит свою работу, что делает работу с промисами проще и улучшает читабельность кода.</dd>
+ <dt><a href="/ru/docs/Learn/JavaScript/Asynchronous/Choosing_the_right_approach">Выбор правильного подхода</a></dt>
+ <dd>В завершение этого модуля, мы рассмотрим технологии и функции, которые мы обсуждали, рассмотрим когда и где их надо использовать. А так же дадим рекомендации и расскажем о распространённых подводных камнях, там где это будет необходимо.</dd>
+</dl>
+
+<h2 id="Смотрите_также">Смотрите также</h2>
+
+<ul>
+ <li><a href="https://eloquentjavascript.net/11_async.html">Асинхронное программирование</a> из фантастической онлайн книги Марина Хавербеке, <a href="https://karmazzin.gitbooks.io/eloquentjavascript_ru/">Выразительный JavaScript</a>.</li>
+</ul>
diff --git a/files/ru/learn/javascript/asynchronous/introducing/index.html b/files/ru/learn/javascript/asynchronous/introducing/index.html
new file mode 100644
index 0000000000..b25ca4037e
--- /dev/null
+++ b/files/ru/learn/javascript/asynchronous/introducing/index.html
@@ -0,0 +1,288 @@
+---
+title: Введение в асинхронный JavaScript
+slug: Learn/JavaScript/Asynchronous/Introducing
+tags:
+ - Асинхронность
+ - Введение
+ - Гайд
+ - Начинающий
+ - Промисы
+ - Статья
+ - колбэк
+ - чейнить
+translation_of: Learn/JavaScript/Asynchronous/Introducing
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Concepts", "Learn/JavaScript/Asynchronous/Timeouts_and_intervals", "Learn/JavaScript/Asynchronous")}}</div>
+
+<p class="summary">В этой статье мы кратко остановимся на проблемах, связанных с синхронным Javascript, а также ознакомимся с несколькими асинхронными методами, демонстрирующими как они могут помочь нам подобные проблемы решить.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Необходимое условие:</th>
+ <td>Базовая компьютерная грамотность, достаточное понимание основ JavaScript.</td>
+ </tr>
+ <tr>
+ <th scope="row">Цель:</th>
+ <td>Ознакомиться с тем, что такое асинхронный JavaScript, чем он отличается от синхронного и в каких случаях используется.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Синхронный_JavaScript">Синхронный JavaScript</h2>
+
+<p>Чтобы (позволить нам) понять что есть <strong>{{Glossary("асинхронный")}}</strong> JavaScript, нам следовало бы для начала убедиться, что мы понимаем что такое <strong>{{Glossary("синхронный")}}</strong> JavaScript. Этот раздел резюмирует некоторую информацию из прошлой статьи.</p>
+
+<p>Большая часть функционала, которую мы рассматривали в предыдущих обучающих модулях, является синхронной — вы запускаете какой-то код, а результат возвращается, как только браузер может его вернуть. Давайте рассмотрим простой пример ( посмотрите <a href="https://mdn.github.io/learning-area/javascript/asynchronous/introducing/basic-function.html">онлайн</a>, как это работает и посмотрите <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/introducing/basic-function.html">исходный код</a>):</p>
+
+<pre class="brush: js notranslate">const btn = document.querySelector('button');
+btn.addEventListener('click', () =&gt; {
+ alert('You clicked me!');
+
+ let pElem = document.createElement('p');
+ pElem.textContent = 'This is a newly-added paragraph.';
+ document.body.appendChild(pElem);
+});
+</pre>
+
+<p>В этом блоке кода команды выполняются одна за другой:</p>
+
+<ol>
+ <li>Получаем ссылку на элемент {{htmlelement("button")}}, который уже есть в DOM.</li>
+ <li>Добавляем к кнопке обработчик события <code><a href="/en-US/docs/Web/API/Element/click_event">click</a></code> так, что при нажатии на неё:
+ <ol>
+ <li>Выводится сообщение <code><a href="/en-US/docs/Web/API/Window/alert">alert()</a></code>.</li>
+ <li>После закрытия сообщения создаём элемент {{htmlelement("p")}} (абзац).</li>
+ <li>Затем добавляем в абзац текст.</li>
+ <li>В конце добавляем созданный абзац в тело документа.</li>
+ </ol>
+ </li>
+</ol>
+
+<p>Пока выполняется каждая операция, ничего больше не может произойти — обработка (отображение) документа приостановлена. Так происходит, как было сказано <a href="/ru/docs/Learn/JavaScript/Asynchronous/Introducing">в предыдущей статье</a>, потому что <a href="/ru/docs/Learn/JavaScript/Asynchronous/Concepts#JavaScript_%D0%BE%D0%B4%D0%BD%D0%BE%D0%BF%D0%BE%D1%82%D0%BE%D1%87%D0%BD%D1%8B%D0%B9">JavaScript является однопоточным</a>. В каждый момент времени может выполняться только одна команда, обрабатываемая в единственном — главном потоке. Все остальные действия блокируются до окончания выполнения текущей команды.</p>
+
+<p>Так и в примере выше: после нажатия кнопки абзац не сможет появиться пока не будет нажата кнопка OK в окне сообщения. Попробуйте сами:</p>
+
+<div class="hidden">
+<pre class="brush: html notranslate">&lt;<span class="pl-ent">button</span>&gt;Нажми меня&lt;/<span class="pl-ent">button</span>&gt;</pre>
+</div>
+
+<p>{{EmbedLiveSample('Synchronous_JavaScript', '100%', '70px')}}</p>
+
+<div class="blockIndicator note">
+<p><strong>Заметка</strong>: Важно помнить, что <code><a href="/en-US/docs/Web/API/Window/alert">alert()</a></code>, хоть и часто используется для демонстрации синхронных блокирующих операций, сильно не рекомендован к использованию в реальных приложениях.</p>
+</div>
+
+<h2 id="Асинхронный_JavaScript">Асинхронный JavaScript</h2>
+
+<p>По причинам, упомянутым ранее (например, относящимся к блокировке), множество Web API особенностей теперь используют асинхронный код, особенно те,что имеют доступ к внешним устройствам или получают от них некоторые ресурсы, такие как получение файла из сети, запрос к базе данных и получение данных из базы, доступ к потоковому видео на веб-камере, просмотр дисплея на гарнитуре виртуальной реальности.</p>
+
+<p>Почему трудно работать, используя синхронный код? Давайте посмотрим на небольшой пример. Когда вы получаете картинку с сервера, вы не можете мгновенно вернуть результат. Это значит что следующий (псевдо) код не сработает:</p>
+
+<pre class="brush: js notranslate">let response = fetch('myImage.png');
+let blob = response.blob();
+// display your image blob in the UI somehow</pre>
+
+<p>Это проиходит потому что вы не знаете сколько времени займет загрузка картинки, следовательно, когда вы начнёте выполнять вторую строку кода, сгенерируется ошибка (возможно, переодически, возможно, каждый раз), потому что <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">response</span></font> еще не доступен. Вместо этого, ваш код должен дождаться возвращения <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">response</span></font> до того, как попытается выполнить дальнешие инструкции.</p>
+
+<p>Есть два типа стиля асинхронного кода, с которыми вы столкнетесь в коде JavaScript, старый метод — callbacks (обратные вызовы) и более новый —  promise (промисы, обещания). В следующих разделах мы познакомимся с каждым из них. </p>
+
+<h2 id="Асинхронные_обратные_вызовы">Асинхронные обратные вызовы</h2>
+
+<p>Асинхронные обратные вызовы — это функции, которые определяются как агрументы при вызове функции, которая начнет выполнение кода на заднем фоне. Когда код на заднем фоне завершает свою работу, он вызвает функцию обратного вызова, оповещающую, что работа сделана, либо оповещающую о трудностях в завершении работы. Обратные вызовы — немного устраревшая практика, но они все еще употребляются в некоторых старомодных, но часто используемых API.</p>
+
+<p>Пример асинхронного обратного вызова вторым параметром {{domxref("EventTarget.addEventListener", "addEventListener()")}} (как мы видели выше):</p>
+
+<pre class="brush: js notranslate">btn.addEventListener('click', () =&gt; {
+ alert('You clicked me!');
+
+ let pElem = document.createElement('p');
+ pElem.textContent = 'This is a newly-added paragraph.';
+ document.body.appendChild(pElem);
+});</pre>
+
+<p>Первый параметр — тип прослушиваемого события, второй параметр — функция обратного вызова, вызываемая при срабатывании события.</p>
+
+<p>При передаче функциии обратного вызова как аргумента в другую функцию, мы передаем только ссылку на функцию как аргумент, следовательно коллбэк функция <strong>не</strong> выполняется мгновенно. Где-то существует "обратный вызов" (отсюда и название), выполняющийся асинхронно внутри тела, содержащего функцию. Эта функция должна выполнять функцию обратногго вызова в нужный момент.</p>
+
+<p>Вы можете написать свою собственную функцию, содержащую функцию обратного вызова. Давайте взглянем на еще один пример, в котором происходит загрузка ресурсов через <a href="/en-US/docs/Web/API/XMLHttpRequest"><code>XMLHttpRequest</code> API</a> (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/introducing/xhr-async-callback.html">запустите пример</a>, и <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/introducing/xhr-async-callback.html">посмотрите исходный код</a>):</p>
+
+<pre class="brush: js notranslate">function loadAsset(url, type, callback) {
+ let xhr = new XMLHttpRequest();
+ xhr.open('GET', url);
+ xhr.responseType = type;
+
+ xhr.onload = function() {
+ callback(xhr.response);
+ };
+
+ xhr.send();
+}
+
+function displayImage(blob) {
+ let objectURL = URL.createObjectURL(blob);
+
+ let image = document.createElement('img');
+ image.src = objectURL;
+ document.body.appendChild(image);
+}
+
+loadAsset('coffee.jpg', 'blob', displayImage);</pre>
+
+<p>Мы создали  функцию <code>displayImage()</code>, которая представляет blob, переданный в нее, как обьект URL, и создает картинку, в которой отображается URL, добавляя ее в элемент документа <code>&lt;body&gt;</code>. Однако, далее мы создаем функцию <code>loadAsset()</code>, которая принимает функцию обратного вызова в качестве параметра, вместе с URL для получения данных и типом контента. Для получения данных из URL используется <code>XMLHttpRequest</code> (часто сокращается до аббревиатуры "XHR") , перед тем как передать ответ в функцию обратного вызова для дальнейшей обработки. В этом случае функция обратного вызова ждет, пока XHR закончит загрузку данных (используя обрабочик события <code><a href="/en-US/docs/Web/API/XMLHttpRequestEventTarget/onload">onload</a></code>) перед отправкой данных в функцию обратного вызова.</p>
+
+<p>Функции обратного вызова универсальны — они не только позволяют вам контролировать порядок, в котором запускаются функции и данные, передающиеся между ними, они также позволяют передавать данные различным функциям, в зависимости от обстоятельств. Вы можете выполнять различные действия с загруженным ответом, такие как  <code>processJSON()</code>, <code>displayText()</code>, и другие.</p>
+
+<p>Заметьте, что не все функции обратного вызова асинхронны — некторые запускаются синхронно. Например, при использовании {{jsxref("Array.prototype.forEach()")}} для перебора элементов массива (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/introducing/foreach.html">запустите пример</a>, и <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/introducing/foreach.html">посмотрите исходный код</a>):</p>
+
+<pre class="brush: js notranslate">const gods = ['Apollo', 'Artemis', 'Ares', 'Zeus'];
+
+gods.forEach(function (eachName, index){
+ console.log(index + '. ' + eachName);
+});</pre>
+
+<p>В этом примере мы перебираем массив с именами греческих богов и выводим индексы и значения в консоль. Ожидаемый параметр для <code>forEach() </code> — это функцияобратного вызова, которая содержит два параметра: ссылку на имя массива и значения индексов. Однако эта функция не ожидает никаких действий — она запускается немедленно.</p>
+
+<h2 id="Промисы">Промисы</h2>
+
+<p>Промисы — новый стиль написания асинхронного кода, который используется в современных Web API. Хорошим примером является <code><a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch">fetch()</a></code> API, который современнее и эффективнее чем {{domxref("XMLHttpRequest")}}. Посмотрим на краткий пример, из нашей статьи <a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Fetching_data">Fetching data from the server</a>:</p>
+
+<pre class="brush: js notranslate">fetch('products.json').then(function(response) {
+  return response.json();
+}).then(function(json) {
+  products = json;
+  initialize();
+}).catch(function(err) {
+  console.log('Ошибка загрузки: ' + err.message);
+});</pre>
+
+<div class="blockIndicator note">
+<p><strong>Заметка</strong>: Вы можете посмотреть законченную версию на github (<a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/fetching-data/can-store-xhr/can-script.js">посмотрите исходный код</a> и <a href="https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store-xhr/">запустите пример</a>).</p>
+</div>
+
+<p>В примере видно, как <code>fetch()</code> принимает один параметр — URL ресурса, который нужно  получить из сети, — и возвращает <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">промис</a>. Промис или обещание — это объект, представляющий асинхронную операцию, выполенную удачно или неудачно. Он представляет собой как бы промежуточное состояние. По сути, это способ браузера сказать: "я обещаю вернуться к вам с ответом как можно скорее," отсюда и название "обещание."</p>
+
+<p>Может пнадобиться много времени, чтобы привыкнуть к данной концепуии; это немного напоминает {{interwiki("wikipedia", "Кот Шрёдингера")}} в действии. Ни один из возможных результатов еще не произошел, поэтому операция fetch в настоящее время ожидает результата. Далее у нас есть три блока кода следующих сразу после <code>fetch()</code>:</p>
+
+<ul>
+ <li>Два <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then">then()</a></code> блока. Оба включают в себя функцию обратного, которая запустится, если предыдущая операция закончилась успешно, и каждая функция обратного вызова принимает на вход результат предыдущей успешно выполненной операции, таким образом вы можете выполнять операции последовательно. Каждый <code>.then()</code> блок возвращает новый promise, это значит что вы можете объеденять в цепочки (чейнить) блоки <code>.then()</code>, таким образом можно выполнить несколько асинхронных операций по порядку, одну за другой.</li>
+ <li><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch">catch()</a></code> блок описывается в конце и будет запущен если какой-либо <code>.then()</code> блок завершится с ошибкой — это аналогично синхронному <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/try...catch">try...catch</a></code>, ошибка становится доступной внутри <code>catch()</code>, что может быть использовано для сообщения пользователю о типе возникшей ошибки. Однако синхронный <code>try...catch</code> не будет работать с promise, хотя будет работать с <a href="/en-US/docs/Learn/JavaScript/Asynchronous/Async_await">async/await</a>, с которыми вы познакомитесь позже.</li>
+</ul>
+
+<div class="blockIndicator note">
+<p><strong>Заметка</strong>: Вы узнаете намного больше о promise позже в этом модуле, так что не волнуйтесь если вы что-нибудь не поняли.</p>
+</div>
+
+<h3 id="Очередь_событий">Очередь событий</h3>
+
+<p>Асинхронные операции, такие как промисы, помещаются в <strong>очередь событий</strong>, которая запускается после завершения обработки основного потока, чтобы они <em>не блокировали</em> выполнение JavaScript кода. Поставленные в очередь операции завершатся как можно скорее, а затем вернут свои результаты в среду JavaScript  .</p>
+
+<h3 id="Промисы_и_функции_обратного_вызова">Промисы и функции обратного вызова</h3>
+
+<p>Промисы имеют некоторое сходство со старомодными функциями обратного вызова. По сути, они являются возвращаемым объектом, к которому вы присоединяете функции обратного вызова, вместо того, чтобы передавать обратные вызовы в функцию.</p>
+
+<p>Тем не менее, промисы сделаны специально для обработки асинхронных операций, и имеют много преимуществ по сравнению с обратными вызовами:</p>
+
+<ul>
+ <li>Вы можете объединить несколько асинхронных операций вместе, используя несколько операций<code>.then()</code>, передавая результат одного в следующий в качестве входных данных. Это гораздо сложнее сделать с обратными вызовами, которые часто заканчиваются массивным «адом обратных вызовов» (также известным как <a href="http://callbackhell.com/">callback hell</a>).</li>
+ <li>Обратные вызовы Promise всегда вызываются в строгом порядке, который они помещают в очередь событий..</li>
+ <li>Обработка ошибок намного лучше — все ошибки обрабатываются одним блоком <code>.catch ()</code> в конце блока, а не обрабатываются индивидуально на каждом уровне «пирамиды».</li>
+ <li>Промисы избегают инверсии управления, в отличие от обратных вызовов, которые теряют полный контроль над тем, как будет выполняться функция при передаче обратного вызова в стороннюю библиотеку.</li>
+</ul>
+
+<h2 id="Природа_асинхронного_кода">Природа асинхронного кода</h2>
+
+<p>Давайте рассмотрим пример, который дополнительно иллюстрирует природу асинхронного кода, показывая, что может произойти, когда мы не полностью осознаем порядок выполнения кода, и проблемы, связанные с попыткой трактовать асинхронный код как синхронный. Следующий пример довольно похож на тот, что мы видели раньше (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/introducing/async-sync.html">запустите пример</a>, и <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/introducing/async-sync.html">посмотрте исходный код</a>). Одно из отличий состоит в том, что мы включили ряд операторов {{domxref("console.log()")}} чтобы проиллюстрировать порядок, в котором, как вы думаете, будет выполняться код.</p>
+
+<pre class="brush: js notranslate">console.log ('Starting');
+let image;
+
+fetch('coffee.jpg').then((response) =&gt; {
+ console.log('It worked :)')
+ return response.blob();
+}).then((myBlob) =&gt; {
+ let objectURL = URL.createObjectURL(myBlob);
+ image = document.createElement('img');
+ image.src = objectURL;
+ document.body.appendChild(image);
+}).catch((error) =&gt; {
+ console.log('There has been a problem with your fetch operation: ' + error.message);
+});
+
+console.log ('All done!');</pre>
+
+<p>Браузер начнет выполнение кода, увидит первый консольный оператор <code>(Starting)</code> и выполнит его, а затем создаст переменную <code>image</code>.</p>
+
+<p>Затем он переместится на следующую строку и начнет выполнять блок <code>fetch ()</code>, но, поскольку <code>fetch ()</code> выполняется асинхронно без блокировки, выполнение кода продолжается после кода, связанного с промисом, тем самым достигая окончательного оператора (<code>All done!</code>) и выводя его на консоль.</p>
+
+<p>Только после того, как блок <code>fetch ()</code> полностью завершит работу и доставит свой результат через блоки <code>.then ()</code>, мы наконец увидим второе сообщение <code>console.log ()</code> (<code>It worked ;)</code>). Таким образом, сообщения появились не в том порядке, который вы могли ожидать:</p>
+
+<ul>
+ <li>Starting</li>
+ <li>All done!</li>
+ <li>It worked :)</li>
+</ul>
+
+<p>Если вы запутались, рассмотрим следующий небольшой пример:</p>
+
+<pre class="brush: js notranslate">console.log("registering click handler");
+
+button.addEventListener('click', () =&gt; {
+ console.log("get click");
+});
+
+console.log("all done");</pre>
+
+<p>Этот пример очень схож с предыдущим в своем поведении —  первое и третье сообщения <code>console.log ()</code> будут показаны немедленно, но второе будет заблокировано, пока кто-то не нажмет кнопку мыши. Предыдущий пример работает аналогичным образом, за исключением того, что в этом случае второе сообщение блокируется цепочкой промисов, получая ресурс, а затем отображая его на экране, а не щелчком мыши.</p>
+
+<p>В менее простом примере кода такая система может вызвать проблему — вы не можете включить блок асинхронного кода, который возвращает результат, на который вы потом будете полагаться в блоке синхронного кода. Вы просто не можете гарантировать, что асинхронная функция вернется до того, как браузер обработает синхронный блок.</p>
+
+<p>Чтобы увидеть это в действии, попробуйте взять локальную копию нашего <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/introducing/async-sync.html">примера</a> и измените третий вызов <code>console.log ()</code> следующим образом:</p>
+
+<pre class="brush: js notranslate">console.log ('All done! ' + image + 'displayed.');</pre>
+
+<p>Теперь вместо третьего сообщения должна возникнуть следующая ошибка:</p>
+
+<pre class="notranslate"><span class="message-body-wrapper"><span class="message-flex-body"><span class="devtools-monospace message-body">TypeError: image is undefined; can't access its "src" property</span></span></span></pre>
+
+<p>Это происходит потому, что в то же время браузер пытается запустить третий <code>console.log()</code>, блок <code>fetch()</code> еще не закончил выполнение, поэтому переменная <code>image</code> еще не имеет значения.</p>
+
+<div class="blockIndicator note">
+<p><strong>Заметка</strong>: Из соображений безопасности вы не можете применять <code>fetch() </code> к файлам из вашей локальной системы (или запустить другие такие операции локально); чтобы запустить локально пример выше вам необходимо запустить его через <a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/Common_questions/set_up_a_local_testing_server">локальный веб-сервер</a>.</p>
+</div>
+
+<h2 id="Активное_обучение_сделайте_все_это_асинхронно!">Активное обучение: сделайте все это асинхронно!</h2>
+
+<p>Чтобы исправить проблемный пример с  <code>fetch()</code> и заставить все три сообщения <code>console.log()</code> появиться в желаемом порядке, вы можете также запустить третье сообщение <code>console.log()</code> асинхронно. Этого можно добиться, переместив его внутрь другого блока <code>.then()</code> присоединенного к концу второго, или просто переместив его внутрь второго блока  <code>then()</code>. Попробуйте иправить это сейчас..</p>
+
+<div class="blockIndicator note">
+<p><strong>Заметка</strong>: Если вы застряли, вы можете <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/introducing/async-sync-fixed.html">найти ответ здесь</a> (также можно посмотреть <a href="https://mdn.github.io/learning-area/javascript/asynchronous/introducing/async-sync-fixed.html">запущенный пример</a>). Также вы можете найти много информации о промисах в нашем гайде <a href="/en-US/docs/Learn/JavaScript/Asynchronous/Promises">Основные понятия асинхронного программирования</a> позднее в этом модуле.</p>
+</div>
+
+<h2 id="Заключение">Заключение</h2>
+
+<p>В своей основной форме JavaScript является синхронным, блокирующим, однопоточным языком, в котором одновременно может выполняться только одна операция. Но веб-браузеры определяют функции и API, которые позволяют нам регистрировать функции, которые не должны выполняться синхронно, а должны вызываться асинхронно, когда происходит какое-либо событие (время, взаимодействие пользователя с мышью или получение данных по сети, например). Это означает, что вы можете позволить своему коду делать несколько вещей одновременно, не останавливая и не блокируя основной поток.</p>
+
+<p>Будем ли мы запускать код синхронно или асинхронно, будет зависеть от того, что мы пытаемся сделать.</p>
+
+<p>Есть моменты, когда мы хотим, чтобы все загружалось и происходило прямо сейчас. Например, при применении некоторых пользовательских стилей к веб-странице вы хотите, чтобы стили применялись как можно быстрее.</p>
+
+<p>Если мы выполняем операцию, которая требует времени, например, запрос к базе данных и использование полученных результатов для заполнения шаблонов, лучше вытолкнуть это из основного потока и выполнить задачу асинхронно. Со временем вы узнаете, когда имеет смысл выбирать асинхронную технику вместо синхронной.</p>
+
+<ul>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Concepts", "Learn/JavaScript/Asynchronous/Timeouts_and_intervals", "Learn/JavaScript/Asynchronous")}}</p>
+
+<h2 id="В_этом_модуле">В этом модуле</h2>
+
+<ul>
+ <li><a href="https://wiki.developer.mozilla.org/ru/docs/Learn/JavaScript/Asynchronous/Concepts">Основные понятия асинхронного программирования</a></li>
+ <li><a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Introducing">Introducing asynchronous JavaScript</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Timeouts_and_intervals">Cooperative asynchronous JavaScript: Timeouts and intervals</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Promises">Graceful asynchronous programming with Promises</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Async_await">Making asynchronous programming easier with async and await</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Choosing_the_right_approach">Choosing the right approach</a></li>
+</ul>
diff --git a/files/ru/learn/javascript/asynchronous/таймауты_и_интервалы/index.html b/files/ru/learn/javascript/asynchronous/таймауты_и_интервалы/index.html
new file mode 100644
index 0000000000..00506c2a14
--- /dev/null
+++ b/files/ru/learn/javascript/asynchronous/таймауты_и_интервалы/index.html
@@ -0,0 +1,638 @@
+---
+title: 'Объединенный асинхронный JavaScript: Таймайты и интервалы'
+slug: Learn/JavaScript/Asynchronous/Таймауты_и_интервалы
+translation_of: Learn/JavaScript/Asynchronous/Timeouts_and_intervals
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Introducing", "Learn/JavaScript/Asynchronous/Promises", "Learn/JavaScript/Asynchronous")}}</div>
+
+<p class="summary">В этом руководстве рассматриваются традиционные методы, доступные в JavaScript для асинхронного выполнения кода по истечении заданного периода времени или через регулярный интервал (например, заданное количество раз в секунду), обсуждаются их полезные свойства и рассматриваются присущие им проблемы. .</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Необходимые условия:</th>
+ <td>Базовая компьютерная грамотность, достаточное понимание основ JavaScript.</td>
+ </tr>
+ <tr>
+ <th scope="row">Цель:</th>
+ <td>Понимание асинхронных циклов и интервалов, и то как их можно использовать.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Введение">Введение</h2>
+
+<p>В течение долгого времени веб-платформа предлагала программистам JavaScript ряд функций, которые позволяли им асинхронно выполнять код по истечении определенного временного интервала и повторно выполнять асинхронный блок кода, пока вы не скажете ему остановиться.</p>
+
+<p>Эти функции:</p>
+
+<dl>
+ <dt><code><a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout">setTimeout()</a></code></dt>
+ <dd>Выполняет указанный блок кода один раз по истечении указанного времени</dd>
+ <dt><code><a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval">setInterval()</a></code></dt>
+ <dd>Выполняет указанный блок кода несколько раз с определенным интервалом между каждым вызовом.</dd>
+ <dt><code><a href="/en-US/docs/Web/API/window/requestAnimationFrame">requestAnimationFrame()</a></code></dt>
+ <dd>Современная версия setInterval (). Выполняут указанный блок кода перед тем, как браузер в следующий раз перерисовывает отображение, позволяя запускать анимацию с подходящей частотой кадров независимо от среды, в которой она выполняется.</dd>
+</dl>
+
+<p>Асинхронный код, установленный этими функциями, выполняется в основном потоке (по истечении указанного им таймера).</p>
+
+<div>
+<p>Важно знать, что вы можете (и часто будете) запускать другой код до выполнения вызова setTimeout () или между итерациями setInterval (). В зависимости от того, насколько интенсивно используются эти операции для процессора, они могут еще больше задержать выполнение асинхронного кода, поскольку любой асинхронный код будет выполняться только после того, как станет доступен основной поток. (Другими словами, когда стек пуст.) Вы узнаете больше по этому вопросу по мере изучения этой статьи.</p>
+</div>
+
+<p>В любом случае эти функции используются для запуска постоянной анимации и другой фоновой обработки на веб-сайте или в приложении. В следующих разделах мы покажем вам, как их можно использовать.</p>
+
+<h2 id="setTimeout">setTimeout()</h2>
+
+<p>Как мы ранее отметили, setTimeout () выполняет определенный блок кода один раз по истечении заданного времени. Принимает следующие параметры:</p>
+
+<ul>
+ <li>Функция для запуска или ссылка на функцию, определенную в другом месте.</li>
+ <li>Число, представляющее интервал времени в миллисекундах (1000 миллисекунд равняется 1 секунде) ожидания перед выполнением кода. Если вы укажете значение 0 (или просто опустите значение), функция запустится как можно скорее. (См. Примечание ниже о том, почему он запускается «как можно скорее», а не «сразу».) Подробнее о том, почему вы, возможно, захотите сделать это позже.</li>
+ <li>Значений, представляющие любые параметры, которые вы хотите передать функции при ее запуске.</li>
+</ul>
+
+<div class="blockIndicator note">
+<p><strong>NOTE: </strong> Указанное время (или задержка) не является гарантированным временем выполнения, а скорее минимальным временем выполнения. Обратные вызовы, которые вы передаете этим функциям, не могут выполняться, пока стек в основном потоке не станет пустым.</p>
+
+<p>Как следствие, такой код, как setTimeout (fn, 0), будет выполняться, как только стек будет пуст, а не сразу. Если вы выполните такой код, как setTimeout (fn, 0), но сразу после выполнения цикла, который насчитывает от 1 до 10 миллиардов, ваш обратный вызов будет выполнен через несколько секунд.</p>
+</div>
+
+<p>В слудующем примере, браузер будет ожидать две секунды перед тем как  выполнит анонимную функцию, тогда отобразит сообщение (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/loops-and-intervals/simple-settimeout.html">живой пример</a>, и <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/loops-and-intervals/simple-settimeout.html">исходный код</a>):</p>
+
+<pre class="brush: js notranslate">let myGreeting = setTimeout(function() {
+ alert('Hello, Mr. Universe!');
+}, 2000)</pre>
+
+<p>Указанные вами функции не обязательно должны быть анонимными. Вы можете дать своей функции имя и даже определить ее где-нибудь еще и передать ссылку на функцию в setTimeout (). Следующие две версии фрагмента кода эквивалентны первой:</p>
+
+<pre class="brush: js notranslate">// С именованной функцией
+let myGreeting = setTimeout(function sayHi() {
+ alert('Hello, Mr. Universe!');
+}, 2000)
+
+// С функцией определенной отдельно
+function sayHi() {
+ alert('Hello Mr. Universe!');
+}
+
+let myGreeting = setTimeout(sayHi, 2000);</pre>
+
+<p>Это может быть полезно, если у вас есть функция, которую нужно вызывать как по таймауту, так например и в ответ на событие. Но это также может  помочь поддерживать ваш код в чистоте, особенно если обратный вызов тайм-аута занимает больше, чем несколько строк кода.</p>
+
+<p><code>setTimeout () </code>возвращает значение идентификатора, которое можно использовать для ссылки на тайм-аут позже, например, когда вы хотите его остановить.</p>
+
+<h3 id="Передача_параметров_в_функцию_setTimeout">Передача параметров в функцию setTimeout ()</h3>
+
+<p>Любые параметры, которые вы хотите передать функции, выполняемой внутри setTimeout (), должны быть переданы ей как дополнительные параметры в конце списка.</p>
+
+<p>Например, вы можете реорганизовать предыдущую функцию, чтобы она передавала привет любому имени, переданному ей:</p>
+
+<pre class="brush: js notranslate">function sayHi(who) {
+ alert(`Hello ${who}!`);
+}</pre>
+
+<p>Теперь вы можете передать имя в вызов setTimeout () в качестве третьего параметра:</p>
+
+<pre class="brush: js notranslate">let myGreeting = setTimeout(sayHi, 2000, 'Mr. Universe');</pre>
+
+<h3 id="Очистка_таймаутов">Очистка таймаутов</h3>
+
+<p>Наконец, если был создан тайм-аут, вы можете отменить его до истечения указанного времени, вызвав <code><a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/clearTimeout">clearTimeout()</a></code>, передав ему идентификатор вызова <code>setTimeout()</code> в качестве параметра. Итак, чтобы отменить указанный выше тайм-аут, вы должны сделать следующее:</p>
+
+<pre class="brush: js notranslate">clearTimeout(myGreeting);</pre>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: См.<code><a href="https://mdn.github.io/learning-area/javascript/asynchronous/loops-and-intervals/greeter-app.html">greeter-app.html</a></code> для более полной демонстрации, которая позволяет вам указать имя для приветствия и отменить приветствие с помощью отдельной кнопки (<a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/loops-and-intervals/greeter-app.html">см. исходный код</a>).</p>
+</div>
+
+<h2 id="setInterval">setInterval()</h2>
+
+<p><code>setTimeout ()</code> отлично работает, когда вам нужно один раз запустить код по истечении заданного периода времени. Но что происходит, когда вам нужно запускать код снова и снова - например, в случае анимации?</p>
+
+<p>Здесь пригодится <a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval">setInterval()</a> . Работает очень похоже на setTimeout (), за исключением того, что функция, которую вы передаете в качестве первого параметра, выполняется повторно не менее чем за количество миллисекунд, заданных вторым параметром. Вы также можете передать любые параметры, необходимые для выполняемой функции, в качестве последующих параметров вызова setInterval ().</p>
+
+<p>Давайте посмотрим на пример. Следующая функция создает новый объект <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date">Date()</a></code>, с помощью <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleTimeString">toLocaleTimeString()</a></code> извлекает из него строку с временем и отображает ее в пользовательском интерфейсе. Затем он запускает функцию один раз в секунду с помощью <code>setInterval()</code>, создавая эффект цифровых часов, которые обновляются раз в секунду (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/loops-and-intervals/setinterval-clock.html"> реальный пример</a>, и <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/loops-and-intervals/setinterval-clock.html">исходный код</a>):</p>
+
+<pre class="brush: js notranslate">function displayTime() {
+ let date = new Date();
+ let time = date.toLocaleTimeString();
+ document.getElementById('demo').textContent = time;
+}
+
+const createClock = setInterval(displayTime, 1000);</pre>
+
+<p>Как и <code>setTimeout ()</code>, <code>setInterval ()</code> возвращает определенное значение, которое вы можете использовать позже, когда вам нужно очистить интервал.</p>
+
+<h3 id="Очистка_интервала">Очистка интервала</h3>
+
+<p><code>setInterval () </code>выполняет задачу постоянно. setInterval () продолжает выполнять задачу вечно, если вы что-то с ней не сделаете. Возможно, вам понадобится способ остановить такие задачи, иначе вы можете получить ошибки, если браузер не сможет выполнить какие-либо другие версии задачи или если анимация, обрабатываемая задачей, завершилась. Вы можете сделать это так же, как останавливаете <code>timeouts</code> - передавая идентификатор, возвращаемый вызовом <code>setInterval ()</code>, в функцию <code>clearInterval ()</code>:</p>
+
+<pre class="brush: js notranslate">const myInterval = setInterval(myFunction, 2000);
+
+clearInterval(myInterval);</pre>
+
+<h4 id="Активное_обучение_Создание_собственного_секундомера!">Активное обучение: Создание собственного секундомера!</h4>
+
+<p>Учитывая все вышесказанное, у нас есть для вас задача. Возьмите копию нашего примера <code><a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/loops-and-intervals/setinterval-clock.html">setInterval-clock.html</a></code> , и измените ее так, чтобы создать свой собственный простой секундомер.</p>
+
+<p>Вам нужно отображать время, как и раньше, но в этом примере вам нужно:</p>
+
+<ul>
+ <li>Кнопка "Start" для запуска секундомера.</li>
+ <li>Кнопка "Stop" для паузы/остановки.</li>
+ <li>Кнопка "Reset", чтобы сбросить счетчик времени на <code>0</code>.</li>
+ <li>Дисплей времени, чтобы отображать количество прошедших секунд а не фактическое время.</li>
+</ul>
+
+<p>Несколько подсказок для вас:</p>
+
+<ul>
+ <li>Вы можете структурировать и стилизовать разметку кнопок по своему усмотрению; просто убедитесь, что вы используете семантический HTML с ковычками, которые позволяют захватывать ссылки на кнопки с помощью JavaScript.</li>
+ <li>Вероятно, вы захотите создать переменную, которая начинается с 0, а затем увеличивается на единицу каждую секунду с использованием постоянного цикла.</li>
+ <li>Этот пример проще создать без использования объекта Date (), как мы это делали в нашей версии, но он будет менее точен - вы не можете гарантировать, что обратный вызов сработает ровно через 1000 мс. Более точным способом было бы запустить startTime = Date.now (), чтобы получить метку времени, когда пользователь нажал кнопку запуска, а затем выполнить Date.now () - startTime, чтобы получить количество миллисекунд после того, как была нажата кнопка запуска .</li>
+ <li>Вам также нужно рассчитать количество часов, минут и секунд как отдельные значения, а затем отображать их вместе в строке после каждой итерации цикла. На втором счетчике вы можете отработать каждую из них.</li>
+ <li>Как вы могли бы их рассчитать? Подумайте об этом:
+ <ul>
+ <li>В одном часе <code>3600 </code>секунд.</li>
+ <li>Количество минут - это количество секунд, оставшееся после вычитания всех часов, разделенное на 60.</li>
+ <li>Количество секунд будет количеством секунд, оставшихся после вычитания всех минут.</li>
+ </ul>
+ </li>
+ <li>Вам необходимо включить начальный ноль в отображаемые значения, если сумма меньше <code>10</code>, чтобы они больше походили на традиционные часы.</li>
+ <li>Чтобы приостановить секундомер, вам нужно очистить интервал. Чтобы сбросить его, вам нудно установить счетчик обратно на <code>0</code>, очистить интервал, а затем немедленно обновить отображение.</li>
+ <li>Вероятно, вам следует отключить кнопку запуска после ее нажатия один раз и снова включить ее после того, как вы остановили / сбросили ее. В противном случае многократное нажатие кнопки запуска приведет к применению нескольких <code>setInterval ()</code> к часам, что приведет к неправильному поведению.</li>
+</ul>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: Если вы застрали, вы можете <a href="https://mdn.github.io/learning-area/javascript/asynchronous/loops-and-intervals/setinterval-stopwatch.html">увидеть нашу версию</a> (см. также <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/loops-and-intervals/setinterval-stopwatch.html">исходный код</a> ).</p>
+</div>
+
+<h2 id="Что_нужно_помнить_о_setTimeout_и_setInterval">Что нужно помнить о <code>setTimeout ()</code> и <code>setInterval ()</code></h2>
+
+<p>При работе с<code> setTimeout ()</code> и <code>setInterval ()</code> следует помнить о нескольких вещах. Давайте рассмотрим их.</p>
+
+<h3 id="Рекурсивые_таймауты">Рекурсивые таймауты</h3>
+
+<p>Есть еще один способ использования <code>setTimeout ()</code>: вы можете вызвать его рекурсивно для повторного запуска одного и того же кода вместо использования <code>setInterval ()</code>.</p>
+
+<p>В приведенном ниже примере используется рекурсивный setTimeout () для запуска переданной функции каждые 100 миллисекунд:</p>
+
+<pre class="brush: js notranslate">let i = 1;
+
+setTimeout(function run() {
+ console.log(i);
+ i++;
+ setTimeout(run, 100);
+}, 100);</pre>
+
+<p>Сравните приведенный выше пример со следующим - здесь используется <code>setInterval ()</code> для достижения того же эффекта:</p>
+
+<pre class="brush: js notranslate">let i = 1;
+
+setInterval(function run() {
+ console.log(i);
+ i++
+}, 100);</pre>
+
+<h4 id="Чем_рекурсивный_setTimeout_отличается_от_setInterval">Чем рекурсивный <code>setTimeout ()</code> отличается от <code>setInterval () </code>?</h4>
+
+<p>Разница между двумя версиями приведенного выше кода невелика.</p>
+
+<ul>
+ <li>Рекурсивный <code>setTimeout ()</code> гарантирует такую же задержку между выполнениями. (Например, 100 мс в приведенном выше случае.) Код будет запущен, затем подождет 100 миллисекунд, прежде чем запустится снова, поэтому интервал будет одинаковым, независимо от того, сколько времени требуется для выполнения кода.</li>
+ <li>Пример с использованием <code>setInterval () </code>работает несколько иначе. Выбранный вами интервал включает время, затрачиваемое на выполнение кода, который вы хотите запустить. Предположим, что выполнение кода занимает <code>40 </code>миллисекунд - тогда интервал составляет всего <code>60 </code>миллисекунд.</li>
+ <li>При рекурсивном использовании <code>setTimeout ()</code> каждая итерация может вычислять различную задержку перед запуском следующей итерации. Другими словами, значение второго параметра может указывать другое время в миллисекундах для ожидания перед повторным запуском кода.</li>
+</ul>
+
+<p>Когда ваш код потенциально может занять больше времени, чем назначенный вами интервал времени, лучше использовать рекурсивный <code>setTimeout ()</code> - это сохранит постоянный временной интервал между выполнениями независимо от того, сколько времени потребуется для выполнения кода, и вы избежите ошибок.</p>
+
+<h3 id="Немедленные_таймауты">Немедленные таймауты</h3>
+
+<p>Использование 0 в качестве значения для <code>setTimeout ()</code> позволяет планировать выполнение указанной функции обратного вызова как можно скорее, но только после того, как будет запущен основной поток кода.</p>
+
+<p>Например, код приведенный ниже (<a href="https://mdn.github.io/learning-area/javascript/asynchronous/loops-and-intervals/zero-settimeout.html">рабочий код</a>) выводит alert содержащий <code>"Hello"</code>, затем alert содержащий <code>"World"</code> как только вы нажмете ОК в первом alert.</p>
+
+<pre class="brush: js notranslate">setTimeout(function() {
+ alert('World');
+}, 0);
+
+alert('Hello');</pre>
+
+<p>Это может быть полезно в тех случаях, когда вы хотите установить блок кода для запуска, как только весь основной поток завершит работу - поместите его в цикл событий async, чтобы он запускался сразу после этого.</p>
+
+<h3 id="Очистка_с_помощью_clearTimeout_или_clearInterval">Очистка с помощью <code>clearTimeout()</code> или <code>clearInterval()</code></h3>
+
+<p>clearTimeout () и <code>clearInterval ()</code> используют один и тот же список записей для очистки. Интересно, что это означает, что вы можете использовать любой метод для очистки setTimeout () или setInterval ().</p>
+
+<p>Для согласованности следует использовать <code>clearTimeout ()</code> для очистки записей <code>setTimeout ()</code> и <code>clearInterval ()</code> для очистки записей <code>setInterval ()</code>. Это поможет избежать путаницы.</p>
+
+<h2 id="requestAnimationFrame">requestAnimationFrame()</h2>
+
+<p><code><a href="/en-US/docs/Web/API/window/requestAnimationFrame">requestAnimationFrame()</a></code> это специализированная функция цикла, созданная для эффективного запуска анимации в браузере. По сути, это современная версия <code>setInterval ()</code> - она выполняет указанный блок кода до того, как браузер перерисовывает изображение, позволяя запускать анимацию с подходящей частотой кадров независимо от среды, в которой она выполняется.</p>
+
+<p>Он был создан в ответ на проблемы с <code>setInterval ()</code>, который, например, не работает с частотой кадров, оптимизированной для устройства, иногда пропускает кадры, продолжает работать, даже если вкладка не является активной вкладкой или анимация прокручивается со страницы и т. д.(<a href="http://creativejs.com/resources/requestanimationframe/index.html">Читай об этом больше в CreativeJS</a>.)</p>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: Вы можете найти примеры использования <code>requestAnimationFrame()</code> в этом курсе — например в  <a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Drawing_graphics">Рисование графики</a>, and <a href="/en-US/docs/Learn/JavaScript/Objects/Object_building_practice">Практика построения объектов</a>.</p>
+</div>
+
+<p>Метод принимает в качестве аргумента обратный вызов, который должен быть вызван перед перерисовкой. Это общий шаблон, в котором он используется:</p>
+
+<pre class="brush: js notranslate">function draw() {
+ // Drawing code goes here
+ requestAnimationFrame(draw);
+}
+
+draw();</pre>
+
+<p>Идея состоит в том, чтобы определить функцию, в которой ваша анимация обновляется (например, ваши спрайты перемещаются, счет обновляется, данные обновляются или что-то еще). Затем вы вызываете его, чтобы начать процесс. В конце функционального блока вы вызываете <code>requestAnimationFrame ()</code> со ссылкой на функцию, переданной в качестве параметра, и это дает браузеру указание вызвать функцию снова при следующей перерисовке дисплея. Затем он выполняется непрерывно, поскольку код рекурсивно вызывает <code>requestAnimationFrame ().</code></p>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: Если вы хотите выполнить простое постоянное анимирование DOM , <a href="/en-US/docs/Web/CSS/CSS_Animations">CSS Анимация</a> вероятно будет быстрее. Она высисляется непосредственно внутренним кодом браузера, а не JavaScript.</p>
+
+<p>Однако, если вы делаете что-то более сложное, включающее объекты, которые не доступны напрямую в the DOM (такие как <a href="/en-US/docs/Web/API/Canvas_API">2D Canvas API</a> или <a href="/en-US/docs/Web/API/WebGL_API">WebGL</a> ), <code>requestAnimationFrame()</code> предпочтительный вариант в большинстве случаев.</p>
+</div>
+
+<h3 id="Как_быстро_работает_ваша_анимация">Как быстро работает ваша анимация?</h3>
+
+<p>Плавность анимации напрямую зависит от частоты кадров анимации и измеряется в кадрах в секунду (fps). Чем выше это число, тем плавнее будет выглядеть ваша анимация до точки.</p>
+
+<p>Поскольку большинство экранов имеют частоту обновления 60 Гц, максимальная частота кадров, к которой вы можете стремиться, составляет 60 кадров в секунду (FPS) при работе с веб-браузерами. Однако большее количество кадров означает больше обработки, которая часто может вызывать заикание и пропуски, также известные как пропадание кадров или заедание.</p>
+
+<p>Если у вас есть монитор с частотой обновления 60 Гц и вы хотите достичь 60 кадров в секунду, у вас есть около 16,7 миллисекунд <code>(1000/60)</code> для выполнения кода анимации для рендеринга каждого кадра. Это напоминание о том, что вам нужно помнить об объеме кода, который вы пытаетесь запустить во время каждого прохождения цикла анимации.</p>
+
+<p><code>requestAnimationFrame ()</code> всегда пытается приблизиться к этому волшебному значению 60 FPS, насколько это возможно. Иногда это невозможно - если у вас действительно сложная анимация и вы запускаете ее на медленном компьютере, частота кадров будет меньше. Во всех случаях<code> requestAnimationFrame ()</code> всегда будет делать все возможное с тем, что у него есть.</p>
+
+<h3 id="Чем_отличается_requestAnimationFrame_от_setInterval_and_setTimeout">Чем отличается requestAnimationFrame() от setInterval() and setTimeout()?</h3>
+
+<p>Давайте поговорим еще немного о том, чем метод <code>requestAnimationFrame ()</code> отличается от других методов, используемых ранее. Глядя на наш код сверху:</p>
+
+<pre class="brush: js notranslate">function draw() {
+ // Drawing code goes here
+ requestAnimationFrame(draw);
+}
+
+draw();</pre>
+
+<p>Такой же код с использованием <code>setInterval()</code>:</p>
+
+<pre class="brush: js notranslate">function draw() {
+ // Drawing code goes here
+}
+
+setInterval(draw, 17);</pre>
+
+<p>Как мы уже говорили ранее, вы не указываете временной интервал для <code>requestAnimationFrame ()</code>. Просто он работает максимально быстро и плавно в текущих условиях. Браузер также не тратит время на запуск, если по какой-то причине анимация выходит за пределы экрана и т. д.</p>
+
+<p><code>setInterval ()</code>, с другой стороны, требует указания интервала. Мы пришли к нашему окончательному значению 17 по формуле 1000 миллисекунд / 60 Гц, а затем округлили его в большую сторону. Округление - хорошая идея; если вы округлите в меньшую сторону, браузер может попытаться запустить анимацию со скоростью, превышающей 60 кадров в секунду, и в любом случае это не повлияет на плавность анимации. Как мы уже говорили, стандартная частота обновления - 60 Гц.</p>
+
+<h3 id="В_том_числе_временная_метка">В том числе временная метка</h3>
+
+<p>Фактическому обратному вызову, переданному в функцию <code>requestAnimationFrame ()</code>, также может быть задан параметр: значение отметки времени, которое представляет время с момента начала работы <code>requestAnimationFrame ().</code></p>
+
+<p>Это полезно, поскольку позволяет запускать вещи в определенное время и в постоянном темпе, независимо от того, насколько быстрым или медленным может быть ваше устройство. Общий шаблон, который вы бы использовали, выглядит примерно так:</p>
+
+<pre class="brush: js notranslate">let startTime = null;
+
+function draw(timestamp) {
+ if (!startTime) {
+ startTime = timestamp;
+ }
+
+ currentTime = timestamp - startTime;
+
+ // Do something based on current time
+
+ requestAnimationFrame(draw);
+}
+
+draw();</pre>
+
+<h3 id="Поддержка_браузерами">Поддержка браузерами</h3>
+
+<p><code>requestAnimationFrame ()</code> поддерживается в более поздних версиях браузеров, чем s<code>etInterval ()</code> / <code>setTimeout ()</code>. Интересно, что он доступен в Internet Explorer 10 и выше.</p>
+
+<p>Итак, если вам не тербуется поддержка старых версий IE, нет особых причин не использовать <code>requestAnimationFrame()</code>.</p>
+
+<h3 id="Простой_пример">Простой пример</h3>
+
+<p>Хватит теории! Давайте выполним упражнение с использованием <code>requestAnimationFrame()</code> . Создадим простую анимацию "spinner animation"—вы могли ее видеть в приложениях когда происходят задержки при ответе с сервера и т.п..</p>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: Для такой простой анимации, вам следовало бы использовать CSS . Однако такой вид анимации очень полезен для демонстрации <code>requestAnimationFrame()</code> , вы скорее всего будете использовать этот метод когда делаете что-то более сложное, например обновление отображения игры в каждом кадре.</p>
+</div>
+
+<ol>
+ <li>
+ <p>Возьмите базовый HTML шаблон (<a href="https://github.com/mdn/learning-area/blob/master/html/introduction-to-html/getting-started/index.html">такой как этот</a>).</p>
+ </li>
+ <li>
+ <p>Поместите пустой  {{htmlelement("div")}} елемент внутри элемента {{htmlelement("body")}}, затем добавьте внутрь символ ↻ . Этот символ будет действовать как spinner в нашем примере.</p>
+ </li>
+ <li>
+ <p>Применитеpply следующий CSS к HTML шаблону (любым предпочитаемым способом). Он установ красный фон на странице, высоту <code>&lt;body&gt;</code> равную <code>100%</code> высоты {{htmlelement("html")}} , и центрирует <code>&lt;div&gt;</code> внутри <code>&lt;body&gt;</code>, по горизонтали и вертикали.</p>
+
+ <pre class="brush: css notranslate">html {
+ background-color: white;
+ height: 100%;
+}
+
+body {
+ height: inherit;
+ background-color: red;
+ margin: 0;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+div {
+ display: inline-block;
+ font-size: 10rem;
+}</pre>
+ </li>
+ <li>
+ <p>Разместите  {{htmlelement("script")}} элемент перед <code>&lt;/body&gt;</code> .</p>
+ </li>
+ <li>
+ <p>Разместите следующий JavaScript код в  <code>&lt;script&gt;</code> . Здесь вы сохраняете ссылку на <code>&lt;div&gt;</code> внутри, устанавливаете дяпеременной <code>rotateCount</code> значение <code>0</code>, устанавливаете неинициализированную переменную, которая позже будет использоваться для хранения ссылки на вызов <code>requestAnimationFrame()</code>, и устанавливатете для переменной <code>startTime</code> значение <code>null</code>, которая будет позже использоваться для хранения времени начала <code>requestAnimationFrame()</code>.</p>
+
+ <pre class="brush: js notranslate">const spinner = document.querySelector('div');
+let rotateCount = 0;
+let startTime = null;
+let rAF;
+</pre>
+ </li>
+ <li>
+ <p>Под предыдущим котом вставьте функцию <code>draw()</code> соторая будет использоваться для хранения нашешо кода анимации, который включает параметр <code>timestamp</code> :</p>
+
+ <pre class="brush: js notranslate">function draw(timestamp) {
+
+}</pre>
+ </li>
+ <li>
+ <p>Внутри <code>draw ()</code> добавьте следующие строки. Они определят время начала, если оно еще не определено (это произойдет только на первой итерации цикла), и установят для параметра <code>rotateCount</code> значение для поворота счетчика (текущая временная метка, возьмите начальную временную метку, разделенную на три, чтобы замедлиться):</p>
+
+ <pre class="brush: js notranslate"> if (!startTime) {
+ startTime = timestamp;
+ }
+
+ rotateCount = (timestamp - startTime) / 3;
+</pre>
+ </li>
+ <li>
+ <p>Под предыдущей строкой внутри <code>draw ()</code> добавьте следующий блок - он проверяет, превышает ли значение <code>rotateCount 359</code> (например, <code>360</code>, полный круг). Если это так, он устанавливает значение по модулю <code>360</code> (то есть остаток, оставшийся после деления значения на <code>360</code>), поэтому круговая анимация может продолжаться непрерывно с разумным низким значением. Обратите внимание, что это не является строго необходимым, но легче работать со значениями от 0 до <code>359</code> градусов, чем со значениями типа «<code>128000</code> градусов».</p>
+
+ <pre class="brush: js notranslate">if (rotateCount &gt; 359) {
+ rotateCount %= 360;
+}</pre>
+ </li>
+ <li>Затем, под предыдущим блоком, добавьте следующую строку, чтобы вращать spinner:
+ <pre class="brush: js notranslate">spinner.style.transform = `rotate(${rotateCount}deg)`;</pre>
+ </li>
+ <li>
+ <p>В самом низу внутри функции <em>draw ()</em> вставьте следующую строку. Это ключ ко всей операции - вы устанавливаете для переменной, определенной ранее, активный вызов<em> requestAnimation ()</em>, который принимает функцию <em>draw ()</em> в качестве своего параметра. Это запускает анимацию, постоянно выполняя функцию <em>draw ()</em> со скоростью, близкой к 60 FPS.</p>
+
+ <pre class="brush: js notranslate">rAF = requestAnimationFrame(draw);</pre>
+ </li>
+ <li>
+ <p>Ниже, вызовите функцию <code>draw()</code> для запуска анимации.</p>
+
+ <pre class="brush: js notranslate">draw();</pre>
+ </li>
+</ol>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: Вы можете посмотреть <a href="https://mdn.github.io/learning-area/javascript/asynchronous/loops-and-intervals/simple-raf-spinner.html">рабочий образец на GitHub</a>. ( <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/loops-and-intervals/simple-raf-spinner.html">исходный код</a>.)</p>
+</div>
+
+<h3 id="Очbстка_вызова_requestAnimationFrame">Очbстка вызова  requestAnimationFrame() </h3>
+
+<p>Очистить вызов <code>requestAnimationFrame ()</code> можно, вызвав соответствующий метод <code>cancelAnimationFrame ()</code>. (Обратите внимание, что имя функции начинается с «cancel», а не «clear», как у методов «set ...».)</p>
+
+<p>Просто передайте ему значение, возвращаемое вызовом requestAnimationFrame () для отмены, которое вы сохранили в переменной rAF:</p>
+
+<pre class="brush: js notranslate">cancelAnimationFrame(rAF);</pre>
+
+<h3 id="Активное_обучение_запуск_и_остановка_нашей_анимации">Активное обучение: запуск и остановка нашей анимации</h3>
+
+<p>В этом упражнении мы хотели бы, чтобы вы протестировали метод <code>cancelAnimationFrame ()</code>, взяв наш предыдущий пример и обновив его, добавив прослушиватель событий для запуска и остановки счетчика при щелчке мышью в любом месте страницы.</p>
+
+<p>Подсказки:</p>
+
+<ul>
+ <li>Обработчик события щелчка можно добавить к большинству элементов, включая документ <code>&lt;body&gt;</code>. Имеет смысл поместить его в элемент <code>&lt;body&gt;</code>, если вы хотите максимизировать интерактивную область - событие всплывает до его дочерних элементов.</li>
+ <li>Вы захотите добавить переменную отслеживания, чтобы проверить, вращается ли счетчик или нет, очистив кадр анимации, если он есть, и снова вызвать его, если это не так.</li>
+</ul>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: Для начала попробуйте сами; если вы действительно застряли, посмотрите наш <a href="https://mdn.github.io/learning-area/javascript/asynchronous/loops-and-intervals/start-and-stop-spinner.html">живой пример</a> и <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/loops-and-intervals/start-and-stop-spinner.html">исходный код</a>.</p>
+</div>
+
+<h3 id="Регулировка_анимации_requestAnimationFrame">Регулировка анимации <code>requestAnimationFrame()</code> </h3>
+
+<p>Одним из ограничений <code>requestAnimationFrame ()</code> является то, что вы не можете выбирать частоту кадров. В большинстве случаев это не проблема, так как обычно вы хотите, чтобы ваша анимация работала как можно плавнее. Но как насчет того, чтобы создать олдскульную 8-битную анимацию?</p>
+
+<p>Это было проблемой, например в анимации ходьбы, вдохновленной островом обезьян, из статьи <a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Drawing_graphics">Drawing Graphics</a>:</p>
+
+<p>{{EmbedGHLiveSample("learning-area/javascript/apis/drawing-graphics/loops_animation/7_canvas_walking_animation.html", '100%', 260)}}</p>
+
+<p>В этом примере вы должны анимировать как положение персонажа на экране, так и отображаемый спрайт. В анимации спрайта всего 6 кадров. Если бы вы показывали разные кадры спрайта для каждого кадра, отображаемого на экране, с помощью requestAnimationFrame (), Guybrush двигал бы конечностями слишком быстро, и анимация выглядела бы нелепо. Следовательно, в этом примере регулируется скорость, с которой спрайт циклически повторяет свои кадры, используя следующий код:</p>
+
+<pre class="brush: js notranslate">if (posX % 13 === 0) {
+ if (sprite === 5) {
+ sprite = 0;
+ } else {
+ sprite++;
+ }
+}</pre>
+
+<p>Таким образом, код циклически повторяет спрайт только один раз каждые 13 кадров анимации.</p>
+
+<p>... Фактически, это примерно каждые 6,5 кадров, поскольку мы обновляем posX (положение персонажа на экране) на два кадра:</p>
+
+<pre class="brush: js notranslate">if (posX &gt; width/2) {
+ newStartPos = -( (width/2) + 102 );
+ posX = Math.ceil(newStartPos / 13) * 13;
+ console.log(posX);
+} else {
+ posX += 2;
+}</pre>
+
+<p>Это код, который вычисляет, как обновлять позицию в каждом кадре анимации.</p>
+
+<p>Метод, который вы используете для регулирования анимации, будет зависеть от вашего конкретного кода. Например, в предыдущем примере счетчика вы могли заставить его двигаться медленнее, увеличивая rotateCount только на единицу в каждом кадре вместо двух.</p>
+
+<h2 id="Активное_обучение_игра_на_реакцию">Активное обучение: игра на реакцию</h2>
+
+<p>В последнем разделе этой статьи вы создадите игру на реакцию для двух игроков. В игре будет два игрока, один из которых управляет игрой с помощью клавиши <kbd>A</kbd>, а другой - с помощью клавиши<kbd> L</kbd>.</p>
+
+<p>При нажатии кнопки «Start» счетчик, подобный тому, что мы видели ранее, отображается в течение случайного промежутка времени от 5 до 10 секунд. По истечении этого времени появится сообщение «PLAYERS GO !!» - как только это произойдет, первый игрок, который нажмет свою кнопку управления, выиграет игру.</p>
+
+<p>{{EmbedGHLiveSample("learning-area/javascript/asynchronous/loops-and-intervals/reaction-game.html", '100%', 500)}}</p>
+
+<p>Давайте поработаем над этим:</p>
+
+<ol>
+ <li>
+ <p>Прежде всего, скачайте <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/loops-and-intervals/reaction-game-starter.html">стартовый файл</a>. Он содержит законченную структуру HTML и стили CSS, что дает нам игровую доску, которая показывает информацию двух игроков (как показано выше), но с счетчиком и параграфом результатов, отображаемыми друг над другом. Вам нужно просто написать JavaScript код.</p>
+ </li>
+ <li>
+ <p>Внутри пустого элемента {{htmlelement("script")}} на вашей старнице, начните с добавления следующих строк кода, котороые определяют некотороые переменные и константы, которые вам понадобятся в дальнейшем:</p>
+
+ <pre class="brush: js notranslate">const spinner = document.querySelector('.spinner p');
+const spinnerContainer = document.querySelector('.spinner');
+let rotateCount = 0;
+let startTime = null;
+let rAF;
+const btn = document.querySelector('button');
+const result = document.querySelector('.result');</pre>
+
+ <p>В следующем порядке:</p>
+
+ <ol>
+ <li>Ссылка на спиннер, чтобы вы могли его анимировать.</li>
+ <li>Ссылка на элемент {{htmlelement("div")}} содержащий спиннер, используемый для отображения и скрытия.</li>
+ <li>Счетчик поворотов. Он определяет, на сколько вы хотите показывать вращение спиннера на каждом кадре анимации.</li>
+ <li>Нулевое время начала. Это будет заполнено временем начала, когда счетчик начнет вращаться.</li>
+ <li>Неинициализировання переменная для последующего хранения вызова {{domxref("Window.requestAnimationFrame", "requestAnimationFrame()")}} который анимирует спиннер.</li>
+ <li>Ссылка на кнопку Start .</li>
+ <li>Ссылка на параграф результатов.</li>
+ </ol>
+ </li>
+ <li>
+ <p>Ниже добавьте следующую функцию. Она просто берет два числа и возвращает случайное число между ними. Это понадобится вам позже, чтобы сгенерировать случайный интервал ожидания.</p>
+
+ <pre class="brush: js notranslate">function random(min,max) {
+ var num = Math.floor(Math.random()*(max-min)) + min;
+ return num;
+}</pre>
+ </li>
+ <li>
+ <p>Затем добавьте функцию draw(), которая анимирует спиннер. Это очень похоже на версию из предыдущего примера просторо счетчика:</p>
+
+ <pre class="brush: js notranslate">function draw(timestamp) {
+ if(!startTime) {
+ startTime = timestamp;
+ }
+
+ rotateCount = (timestamp - startTime) / 3;
+
+ if(rotateCount &gt; 359) {
+ rotateCount %= 360;
+ }
+
+ spinner.style.transform = 'rotate(' + rotateCount + 'deg)';
+ rAF = requestAnimationFrame(draw);
+}</pre>
+ </li>
+ <li>
+ <p>Теперь пришло время настроить начальное состояние приложения при первой загрузке страницы. Добавьте следующие две строки, которые просто скрывают абзац результатов и контейнер счетчика с помощью <code>display: none</code> ;.</p>
+
+ <pre class="brush: js notranslate">result.style.display = 'none';
+spinnerContainer.style.display = 'none';</pre>
+ </li>
+ <li>
+ <p>Затем определите функцию<code> reset ()</code>, которая возвращает приложение в исходное состояние, необходимое для повторного запуска игры после ее завершения. Добавьте в конец кода следующее:</p>
+
+ <pre class="brush: js notranslate">function reset() {
+ btn.style.display = 'block';
+ result.textContent = '';
+ result.style.display = 'none';
+}</pre>
+ </li>
+ <li>
+ <p>Хорошо, хватит подготовки! Пришло время сделать игру доступной! Добавьте в свой код следующий блок. Функция <code>start ()</code> вызывает <code>draw ()</code>, чтобы запустить вращение спиннера и отобразить его в пользовательском интерфейсе, скрыть кнопку Start, чтобы вы не могли испортить игру, запустив ее несколько раз одновременно, и запускает вызов <code>setTimeout ()</code>, который выполняется функция <code>setEndgame ()</code> по прошествии случайного интервала от 5 до 10 секунд. Следующий блок также добавляет прослушиватель событий к вашей кнопке для запуска функции <code>start ()</code> при ее нажатии.</p>
+
+ <pre class="brush: js notranslate">btn.addEventListener('click', start);
+
+function start() {
+ draw();
+ spinnerContainer.style.display = 'block';
+ btn.style.display = 'none';
+ setTimeout(setEndgame, random(5000,10000));
+}</pre>
+
+ <div class="blockIndicator note">
+ <p><strong>Note</strong>: Вы увидете, что этот пример вызывает <code>setTimeout()</code> без сохранения возвращаемого значения. (не  <code>let myTimeout = setTimeout(functionName, interval)</code>.) </p>
+
+ <p>Это прекрасно работает, если вам не нужно очищать интервал / тайм-аут в любой момент. Если вы это сделаете, вам нужно будет сохранить возвращенный идентификатор!</p>
+ </div>
+
+ <p>Конечным результатом предыдущего кода является то, что при нажатии кнопки «Start» отображается спиннер, и игроки вынуждены ждать произвольное количество времени, прежде чем их попросят нажать их кнопку. Эта последняя часть обрабатывается функцией <code>setEndgame ()</code>, которую вы определите позже.</p>
+ </li>
+ <li>
+ <p>Добавьте в свой код следующую функцию:</p>
+
+ <pre class="brush: js notranslate">function setEndgame() {
+ cancelAnimationFrame(rAF);
+ spinnerContainer.style.display = 'none';
+ result.style.display = 'block';
+ result.textContent = 'PLAYERS GO!!';
+
+ document.addEventListener('keydown', keyHandler);
+
+ function keyHandler(e) {
+ let isOver = false;
+ console.log(e.key);
+
+ if (e.key === "a") {
+ result.textContent = 'Player 1 won!!';
+ isOver = true;
+ } else if (e.key === "l") {
+ result.textContent = 'Player 2 won!!';
+ isOver = true;
+ }
+
+ if (isOver) {
+ document.removeEventListener('keydown', keyHandler);
+ setTimeout(reset, 5000);
+ }
+ };
+}</pre>
+
+ <p>Пройдите через это:</p>
+
+ <ol>
+ <li>Во-первых, отмените анимацию спиннера с помощью {{domxref("window.cancelAnimationFrame", "cancelAnimationFrame()")}} (всегда полезно очистить ненужный процессы), и скройте контейнер счетчика.</li>
+ <li>Затем, отобразите абзац с результатами и установите для его текстового содержимого значение "PLAYERS GO!!"  чтобы сообщить игрокам, что теперь они могут нажать свою кнопку, чтобы победить.</li>
+ <li>Прикрепите к документу прослушиватель событий <code><a href="/en-US/docs/Web/API/Document/keydown_event">keydown</a></code> . При нажатии любой кнопки запускается функция <code>keyHandler()</code>.</li>
+ <li>Внутри <code>keyHandler()</code>, код включает обьект события в качестве параметра (представленного <code>e</code>) — его свойство {{domxref("KeyboardEvent.key", "key")}} содержит только что нажатую клавишу, и вы можете использовать это для твета на определенные нажатия клавиш определенными действиями.</li>
+ <li>Установите для переменной <code>isOver</code> значение false, чтобы мы могли отслеживать, были ли нажаты правильные клавиши, чтобы игрок 1 или 2 выиграл. Мы не хотим, чтобы игра заканчивалась при нажатии неправильной клваиши.</li>
+ <li>Регистрация <code>e.key</code> в консоли, это полезный способ узнать значение различных клавиш, которые вы нажимаете.</li>
+ <li>Когда <code>e.key</code> принимает значение "a", отобразить сообщение о том, что Player 1 выиграл, а когда <code>e.key</code> это "l", отобразить сообщение о том, что Player 2 выиграл. (<strong>Note:</strong> Это будет работать только со строчными буквами a и l — если переданы прописные A или L , это считается другими клавишами!) Если была нажата одна из этих клавишь, установите для <code>isOver</code> значение <code>true</code>.</li>
+ <li>Только еслиf <code>isOver</code> равно <code>true</code>, удалите прослушиватель событий <code>keydown</code> с помощью {{domxref("EventTarget.removeEventListener", "removeEventListener()")}} чтобы после того, как произошло выигрышное нажатие, больше не было возможности ввода с клавиатуры, чтобы испортить финальный результат игры. Вы также используете <code>setTimeout()</code> для вызова <code>reset()</code> через 5 секунд — как обьяснялось ранее, эта функция сбрасывает игру обратно в исходное состояние, чтобы можно было начать новую игру.</li>
+ </ol>
+ </li>
+</ol>
+
+<p>Вот и все - вы справились!</p>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: Если вы где то застряли, взгляните на <a href="https://mdn.github.io/learning-area/javascript/asynchronous/loops-and-intervals/reaction-game.html">наша версия игры</a> (см. также <a href="https://github.com/mdn/learning-area/blob/master/javascript/asynchronous/loops-and-intervals/reaction-game.html">исходный код</a> ).</p>
+</div>
+
+<h2 id="Заключение">Заключение</h2>
+
+<p>Вот и все — все основы асинхронных циклов и интервалов рассмотрены в статье. Вы найдете эти методы полезными во многих ситуациях, но постарайтесь не злоупотреблять ими! Поскольку они по-прежнему выполняются в основном потоке, тяжелые и интенсивные обратные вызовы (особенно те, которые управляют DOM) могут действительно замедлить страницу, если вы не будете осторожныl.</p>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Introducing", "Learn/JavaScript/Asynchronous/Promises", "Learn/JavaScript/Asynchronous")}}</p>
+
+<h2 id="В_этом_модуле">В этом модуле</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Concepts">Основные понятия асинхронного программирования</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Introducing">Введение в асинхронный JavaScript</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Timeouts_and_intervals">Обьединенный асинхронный JavaScript: Таймауты и интервалы</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Promises">Graceful asynchronous programming with Promises</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Async_await">Сделайте асинхронное программирование легче с async и await</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Asynchronous/Choosing_the_right_approach">Choosing the right approach</a></li>
+</ul>
+
+<div id="gtx-trans" style="position: absolute; left: 70px; top: 13746px;">
+<div class="gtx-trans-icon"></div>
+</div>
diff --git a/files/ru/learn/javascript/building_blocks/build_your_own_function/index.html b/files/ru/learn/javascript/building_blocks/build_your_own_function/index.html
new file mode 100644
index 0000000000..fab6711d39
--- /dev/null
+++ b/files/ru/learn/javascript/building_blocks/build_your_own_function/index.html
@@ -0,0 +1,254 @@
+---
+title: Создайте свою функцию
+slug: Learn/JavaScript/Building_blocks/Build_your_own_function
+translation_of: Learn/JavaScript/Building_blocks/Build_your_own_function
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Functions","Learn/JavaScript/Building_blocks/Return_values", "Learn/JavaScript/Building_blocks")}}</div>
+
+<p class="summary">Эта статья призвана дать практический опыт на основе теоретических знаний приведенныйх в<a href="/ru/docs/Learn/JavaScript/Building_blocks/Functions"> предыдущей статье</a>. Попутно мы также объясним некоторые важные детали работы с функциями.<br>
+  </p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Предпосылки:</th>
+ <td>Базовая компьютерная грамотность, базовое понимание HTML и CSS, <a href="/ru/docs/Learn/JavaScript/Первые_шаги">первые шаги в JavaScript</a>, <a href="/ru/docs/Learn/JavaScript/Building_blocks/Functions">Функции — блоки кода используемые многократно</a>.</td>
+ </tr>
+ <tr>
+ <th scope="row">Задача:</th>
+ <td>Научить создавать пользовательской функции и объяснить еще несколько полезных деталей.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Активное_обучение_пострение_функции">Активное обучение: пострение функции</h2>
+
+<p>Пользовательская функция, которую мы собираемся построить, будет называться <code>displayMessage()</code>. Она отобразит настраиваемое окно сообщения на веб-странице и будет действовать как настраиваемая замена встроенной в браузер функции <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/alert">alert()</a>. Мы видели эту функцию раньше. Введите следующую команду в консоли JavaScript браузера на любой странице:</p>
+
+<pre class="brush: js">alert('This is a message');</pre>
+
+<p>Функция <code>alert</code> принимает один аргумент - строку, которая отображается в окне сообщения на веб-странице Попробуйте изменить строку, чтобы изменить сообщение.</p>
+
+<p>Функция <code>alert</code> ограничена: вы можете изменить текст сообщения, но не получится изменить его стиль, например, цвет, значок или что-то еще. Создадим сообщение, более интересное по стилю.</p>
+
+<div class="note">
+<p><strong>Примечание</strong>: Этот пример будет работать во всех современных браузерах, но стиль может выглядеть немного смешным в более старых браузерах. Мы рекомендуем вам выполнять это упражнение в современном браузере, таком как Firefox, Opera или Chrome.</p>
+</div>
+
+<h2 id="Основная_функция">Основная функция</h2>
+
+<p>Для начала давайте соберем основную функцию.</p>
+
+<div class="note">
+<p><strong>Примечание</strong>: Для согласований имен функций нужно следовать тем же правилам, что и <a href="/ru/docs/Learn/JavaScript/Первые_шаги/Variables#Правила_именования_переменных">правила именования переменных</a>. Отличить имена функций от имен переменных просто: после имен функций указываются круглые скобки, а после имен переменных их нет.</p>
+</div>
+
+<ol>
+ <li>Откройте файл <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/functions/function-start.html">function-start.html</a> и скопируйте его себе на компьютер. Код HTML в нем предельно прост: body содержит только одну кнопку. Также здесь представлен базовый CSS для создания настраиваемого окна сообщений и пустой элемент {{htmlelement ("script")}} для размещения нашего JavaScript.</li>
+ <li>Затем добавьте строку внутри элемента <code>&lt;script&gt;</code>:
+ <pre class="brush: js">function displayMessage() {
+
+}</pre>
+ Мы начинаем с ключевого слова <code>function</code>, что означает, что мы определяем функцию. За ним следует имя, которое мы хотим дать нашей функции, набор круглых скобок и набор фигурных скобок. Любые параметры, которые мы хотим задать нашей функции, заключают в круглые скобки, а код, который запускается при вызове функции, находится внутри фигурных скобок.</li>
+ <li>Наконец, добавьте следующий код внутри фигурных скобок:
+ <pre class="brush: js">var html = document.querySelector('html');
+
+var panel = document.createElement('div');
+panel.setAttribute('class', 'msgBox');
+html.appendChild(panel);
+
+var msg = document.createElement('p');
+msg.textContent = 'This is a message box';
+panel.appendChild(msg);
+
+var closeBtn = document.createElement('button');
+closeBtn.textContent = 'x';
+panel.appendChild(closeBtn);
+
+closeBtn.onclick = function() {
+ panel.parentNode.removeChild(panel);
+}</pre>
+ </li>
+</ol>
+
+<p>Рассмотрим этот код по строкам (прим. - в оригинале статьи: "bit by bit").</p>
+
+<p>В первой строке используется функция DOM API под именем {{domxref ("document.querySelector()")}} для выбора элемента {{htmlelement ("html")}}, сохраняющая ссылку на него в переменной <code>html</code>, чтобы позже мы могли с ней что-то сделать:</p>
+
+<pre class="brush: js">var html = document.querySelector('html');</pre>
+
+<p>В следующем разделе используется другая функция DOM API, называемая {{domxref ("Document.createElement()")}}, применяется для создания элемента {{htmlelement ("div")}} и сохраняет ссылку на него в переменной, называемой <code>panel</code>. Этот элемент будет внешним контейнером нашего окна сообщений.</p>
+
+<p>Затем мы используем еще одну функцию DOM API, называемую {{domxref ("Element.setAttribute()")}}, чтобы установить атрибут <code>class</code> на нашей панели со значением <code>msgBox</code>. Это упрощает стилизацию элемента. Если вы посмотрите на CSS на странице, вы увидите, что мы используем селектор класса <code>.msgBox</code> для стилизации окна сообщения и его содержимого.</p>
+
+<p>Наконец, мы вызываем функцию DOM с именем {{domxref ("Node.appendChild()")}} в переменной <code>html</code>, которую мы сохранили ранее, которая вкладывает один элемент в другой как его дочерний элемент. Указываем панель <code>&lt;div&gt;</code> как дочерний элемент, который мы хотим вложить внутрь элемента <code>&lt;html&gt;</code>. То есть, когда мы создаем какой-то элемент, он не просто будет отображаться на странице сам по себе, нам нужно указать, куда его поместить.</p>
+
+<pre class="brush: js">var panel = document.createElement('div');
+panel.setAttribute('class', 'msgBox');
+html.appendChild(panel);</pre>
+
+<p>В следующих двух разделах используются те же функции <code>createElement()</code> и <code>appendChild()</code>, которые мы уже видели, чтобы создать два новых элемента: {{htmlelement ("p")}} и {{htmlelement ("button")}}, и вставить их на страницу, как дочерних элементов панели <code>&lt;div&gt;</code>. Мы используем свойство {{domxref ("Node.textContent")}}, которое представляет текстовое содержимое элемента, для вставки сообщения внутри абзаца и символ «x» внутрь кнопки. Нажатие/активация этой кнопки будет закрывать окно сообщения.</p>
+
+<pre class="brush: js">var msg = document.createElement('p');
+msg.textContent = 'This is a message box';
+panel.appendChild(msg);
+
+var closeBtn = document.createElement('button');
+closeBtn.textContent = 'x';
+panel.appendChild(closeBtn);</pre>
+
+<p>В заключении мы используем обработчик событий {{domxref ("GlobalEventHandlers.onclick")}}, чтобы при нажатии кнопки был запущен некоторый код для удаления всей панели со страницы, т.е. для закрытия окна сообщения.</p>
+
+<p>Вкратце, обработчик <code>onclick</code> — это свойство, доступное для кнопки (или, фактически, для любого элемента страницы), которое можно установить в функцию, чтобы указать, какой код следует запускать при нажатии кнопки. Вы узнаете об этом больше в нашей статье о последующих событиях. Мы делаем обработчик <code>onclick</code> равным анонимной функции, которая содержит код, запускаемый при нажатии кнопки. Строка внутри функции использует функцию {{domxref ("Node.removeChild()")}} DOM API, чтобы указать, что мы хотим удалить определенный дочерний элемент внутри HTML — в данном случае панель <code>&lt;div&gt;</code>.</p>
+
+<pre class="brush: js">closeBtn.onclick = function() {
+ panel.parentNode.removeChild(panel);
+}</pre>
+
+<p>В принципе, весь этот блок кода генерирует блок HTML, который выглядит так и вставляет его на страницу:</p>
+
+<pre class="brush: html">&lt;div class="msgBox"&gt;
+ &lt;p&gt;This is a message box&lt;/p&gt;
+ &lt;button&gt;x&lt;/button&gt;
+&lt;/div&gt;</pre>
+
+<p>Вам не обязательно запоминать сейчас, как работает каждый элемент во всем этом коде. Основная задача — понять структуру и использование функции, при этом мы хотели показать что-то интересное для этого примера.</p>
+
+<h2 id="Вызов_функции">Вызов функции</h2>
+
+<p>Теперь у вас есть определение функции, написанное в вашем элементе <code>&lt;script&gt;</code>, но оно ничего не будет делать в том виде, в каком оно есть.</p>
+
+<ol>
+ <li>Попробуйте написать следующую строку под своей функцией, чтобы вызвать ее:
+ <pre class="brush: js">displayMessage();</pre>
+ Эта строка вызывает функцию, немедленно запуская ее. Когда вы сохраните код и перезагрузите его в браузере, вы увидите, что небольшое окно сообщения появляется сразу и только один раз.</li>
+ <li>
+ <p>Теперь откройте инструменты разработчика браузера на странице примера, перейдите в консоль JavaScript и снова введите эту строку. Вы увидите, что окно появится снова! Теперь у нас есть функция многократного использования, которую мы можем вызвать в любое время.</p>
+
+ <p>Но мы, вероятно, хотим, чтобы оно появлялось в ответ на действия пользователя и системы. В реальном приложении такое окно сообщения, вероятно, будет вызвано в ответ на доступность новых данных или, если произошла ошибка, или, например, если пользователь пытаюется удалить свой профиль («вы уверены в этом?»), или если пользователь добавляет новый контакт и операция успешно завершена и т. д.</p>
+
+ <p>В этой демонстрации мы получим окно сообщения, когда пользователь нажимает кнопку.</p>
+ </li>
+ <li>Удалите предыдущую добавленную строку.</li>
+ <li>Затем мы выберем кнопку и сохраним ссылку на нее в переменной. Добавьте следующую строку в свой код, над определением функции:
+ <pre class="brush: js">var btn = document.querySelector('button');</pre>
+ </li>
+ <li>Наконец, добавьте следующую строку ниже предыдущей:
+ <pre class="brush: js">btn.onclick = displayMessage;</pre>
+ Аналогично нашей строке <code>closeBtn.onclick...</code> внутри функции здесь мы вызываем некоторый код в ответ на нажатие кнопки. Но в этом случае вместо вызова анонимной функции, содержащей некоторый код, мы вызываем имя нашей функции напрямую.</li>
+ <li>Сохраните и обновите страницу. Теперь вы должны увидеть окно с сообщением, когда вы нажимаете кнопку.</li>
+</ol>
+
+<p>Возможно, вам интересно, почему мы не включили круглые скобки после имени функции. Это связано с тем, что нам нужно не сразу вызвать функцию, а только после нажатия кнопки. Если вы попытаетесь изменить строку на</p>
+
+<pre class="brush: js">btn.onclick = displayMessage();</pre>
+
+<p>сохраните и перезагрузите страницу, вы увидите, что окно сообщения появляется без нажатия кнопки! Скобки в этом контексте иногда называют «оператором вызова функции». Вы используете их только в том случае, если хотите немедленно запустить функцию в текущей области. В этом же отношении код внутри анонимной функции не запускается сразу, так как он находится внутри области функций.</p>
+
+<p>Если вы пробовали последний эксперимент, перед тем, как продолжить, обязательно отмените последнее изменение.</p>
+
+<h2 id="Улучшение_функции_с_параметрами">Улучшение функции с параметрами</h2>
+
+<p>В нынешнем виде функция по-прежнему не очень полезна — мы не хотим показывать одно и то же сообщение по умолчанию каждый раз. Давайте улучшим нашу функцию, добавив некоторые параметры, позволяющие нам называть ее различными вариантами.</p>
+
+<ol>
+ <li>
+ <p>Прежде всего, обновите первую строку функции:</p>
+
+ <pre class="brush: js">function displayMessage() {</pre>
+
+ <p>к этому:</p>
+
+ <pre class="brush: js">function displayMessage(msgText, msgType) {</pre>
+ Теперь, когда мы вызываем функцию, мы можем предоставить два значения переменных в круглых скобках, чтобы указать сообщение для отображения в окне сообщения, а также тип сообщения.</li>
+ <li>Чтобы использовать первый параметр, обновите следующую строку внутри своей функции:
+ <pre class="brush: js">msg.textContent = 'This is a message box';</pre>
+
+ <p>к этому:</p>
+
+ <pre class="brush: js">msg.textContent = msgText;</pre>
+ </li>
+ <li>И последнее, но не менее важное: теперь вам нужно обновить вызов функции, чтобы включить в него обновленный текст сообщения. Измените следующую строку:
+ <pre class="brush: js">btn.onclick = displayMessage;</pre>
+
+ <p>к этому блоку:</p>
+
+ <pre class="brush: js">btn.onclick = function() {
+ displayMessage('Woo, this is a different message!');
+};</pre>
+ Если мы хотим указать параметры в круглых скобках для вызываемой нами функции, то мы не можем назвать ее напрямую, нам нужно поместить ее в анонимную функцию, чтобы она не находилась непосредственно в области видимости и, следовательно, не вызывалась немедленно. Теперь она не будет вызываться до нажатия кнопки.</li>
+ <li>Перезагрузите и протестируйте код еще раз, и вы увидите, что он по-прежнему работает, только теперь вы также можете изменять сообщение внутри параметра, чтобы отображать разные сообщения в окне.</li>
+</ol>
+
+<h3 id="Более_сложный_параметр">Более сложный параметр</h3>
+
+<p>Переход к следующему параметру. Это потребует немного больше работы. Установим его так, чтобы в зависимости от того, какой параметр <code>msgType</code> установлен, функция отображала другой значок и другой цвет фона.</p>
+
+<ol>
+ <li>Для начала, загрузите значки, необходимые для этого упражнения (<a href="https://raw.githubusercontent.com/mdn/learning-area/master/javascript/building-blocks/functions/icons/warning.png">warning</a> и <a href="https://raw.githubusercontent.com/mdn/learning-area/master/javascript/building-blocks/functions/icons/chat.png">chat</a> [тут черные иконки на черном фоне... тролли на GitHub]) из GitHub. Сохраните их в новой папке <code>icons</code> в том же месте, что и ваш HTML-файл.
+
+ <div class="note"><strong>Примечание</strong>: иконки <a href="https://www.iconfinder.com/icons/1031466/alarm_alert_error_warning_icon">warning</a> и <a href="https://www.iconfinder.com/icons/1031441/chat_message_text_icon">chat</a> были найдены на <a href="https://www.iconfinder.com/" rel="noopener">iconfinder.com</a>, и разработаны <a href="https://www.iconfinder.com/nazarr">Nazarrudin Ansyari</a>. Спасибо! (Фактические страницы значков были перемещены или удалены.) </div>
+ </li>
+ <li>Затем найдите CSS внутри вашего HTML-файла. Мы сделаем несколько изменений, чтобы освободить место для иконок. Во-первых, обновите ширину <code>.msgBox</code>:
+ <pre class="brush: css">width: 200px;</pre>
+
+ <p>измените на:</p>
+
+ <pre class="brush: css">width: 242px;</pre>
+ </li>
+ <li>Затем добавьте следующие строки в правило <code>.msgBox p { ... }</code> :
+ <pre class="brush: css">padding-left: 82px;
+background-position: 25px center;
+background-repeat: no-repeat;</pre>
+ </li>
+ <li>Теперь нам нужно добавить код в нашу функцию <code>displayMessage()</code>для обработки отображений значков. Добавьте следующий блок чуть выше закрывающей фигурной скобки "<code>}</code>" вашей функции:
+ <pre class="brush: js">if (msgType === 'warning') {
+ msg.style.backgroundImage = 'url(icons/warning.png)';
+ panel.style.backgroundColor = 'red';
+} else if (msgType === 'chat') {
+ msg.style.backgroundImage = 'url(icons/chat.png)';
+ panel.style.backgroundColor = 'aqua';
+} else {
+ msg.style.paddingLeft = '20px';
+}</pre>
+ Здесь, если параметр <code>msgType</code> установлен как <code>'warning'</code>, отображается значок предупреждения, а цвет фона панели устанавливается красным. Если для него установлено значение<code>'chat'</code>, отображается значок чата, а цвет фона панели становится голубым. Если параметр <code>msgType</code> не задан вообще (или задано что-то другое), тогда вступает в действие <code>else {...}</code>, а абзацу просто присваиваются заданные по умолчанию отступы, нет никакого значка, при этом не задается цвет фона окна сообщения. Это обеспечивает состояние по умолчанию, если не указан параметр <code>msgType</code>, что означает, что это необязательный параметр!</li>
+ <li>Давайте протестируем нашу обновленную функцию, попробуем обновить вызов displayMessage () из этого:
+ <pre class="brush: js">displayMessage('Woo, this is a different message!');</pre>
+
+ <p>к одному из них:</p>
+
+ <pre class="brush: js">displayMessage('Your inbox is almost full — delete some mails', 'warning');
+displayMessage('Brian: Hi there, how are you today?','chat');</pre>
+ Вот, насколько полезной становится наша (теперь не очень) маленькая функция.</li>
+</ol>
+
+<div class="note">
+<p><strong>Примечание</strong>: Если у вас возникли проблемы с запуском примера, не стесняйтесь проверять свой код на готовой версии <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/functions/function-stage-4.html">GitHub</a> (см. также <a href="https://mdn.github.io/learning-area/javascript/building-blocks/functions/function-stage-4.html">в режиме реального времени</a>) или обратитесь к нам за помощью.</p>
+</div>
+
+<h2 id="Вывод">Вывод</h2>
+
+<p>В этой статье мы познакомились со всем процессом создания практической пользовательской функции, которую с небольшими доработками можно перенести в реальный проект. В следующей статье мы рассмотрим еще одну важную концепцию — возвращаемые значения функций.</p>
+
+<ul>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Functions","Learn/JavaScript/Building_blocks/Return_values", "Learn/JavaScript/Building_blocks")}}</p>
+
+<p> </p>
+
+<h2 id="В_этом_модуле">В этом модуле</h2>
+
+<ul>
+ <li><a href="/ru/docs/Learn/JavaScript/Building_blocks/conditionals">Принятие решений в Вашем коде — условные конструкции</a></li>
+ <li><a href="/ru/docs/Learn/JavaScript/Building_blocks/Looping_code">Зацикливание кода</a></li>
+ <li><a href="/ru/docs/Learn/JavaScript/Building_blocks/Functions">Функции — Переиспользуемые блоки кода</a></li>
+ <li><a href="/ru/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">Создайте свою собственную функцию</a></li>
+ <li><a href="/ru/docs/Learn/JavaScript/Building_blocks/Return_values">Возвращаемое значение функции</a></li>
+ <li><a href="/ru/docs/Learn/JavaScript/Building_blocks/События">Введение в события</a></li>
+ <li><a href="/ru/docs/Learn/JavaScript/Building_blocks/Image_gallery">Создание галереи</a></li>
+</ul>
+
+<p> </p>
diff --git a/files/ru/learn/javascript/building_blocks/conditionals/index.html b/files/ru/learn/javascript/building_blocks/conditionals/index.html
new file mode 100644
index 0000000000..970c31d43b
--- /dev/null
+++ b/files/ru/learn/javascript/building_blocks/conditionals/index.html
@@ -0,0 +1,746 @@
+---
+title: Принятие решений в Вашем коде — условные конструкции
+slug: Learn/JavaScript/Building_blocks/conditionals
+tags:
+ - JavaScript
+ - Switch
+ - else
+ - if
+ - Для начинающих
+ - Операторы
+ - Статья
+translation_of: Learn/JavaScript/Building_blocks/conditionals
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{NextMenu("Learn/JavaScript/Building_blocks/Looping_code", "Learn/JavaScript/Building_blocks")}}</div>
+
+<p class="summary">Во многих языках программирования код должен иметь возможность принимать решения на основе введеных пользователем данных. Например, в игре, если у пользователя осталось 0 жизней, то игра завершается. В приложении о погоде утром отображается восход солнца, а вечером звезды и луна. В этой статье мы рассмотрим как в  JavaScript работают так называемые "условия".</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Необходимое условие:</th>
+ <td>Базовая компьютерная грамотность, базовое понимание HTML и CSS, <a href="/en-US/docs/Learn/JavaScript/First_steps">JavaScript first steps</a>.</td>
+ </tr>
+ <tr>
+ <th scope="row">Цель:</th>
+ <td>Понять принципы использования операторов условий в JavaScript.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Выбор_одного_условия!..">Выбор одного условия!..</h2>
+
+<p>Люди (и животные) принимают какие-либо решения всю жизнь, от малозначимых ("стоит ли мне съесть одну печеньку или две?") до жизнеопределяющих ("стоит ли мне остаться дома и работать на ферме отца или переехать в другую страну и изучать астрофизику?")</p>
+
+<p>Операторы условия в JavaScript позволяют нам указать разного рода действия в зависимости от выбранного пользователем или системой ответа (например одна печенька или две) и связать его с действием (результатом), например, результатом "съесть одну печеньку" будет "все еще буду чуствовать себя голодным", а результатом "съесть две печеньки" будет "буду чуствовать себя сытым, но мама меня наругает за то, что я съел все сладости". </p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13703/cookie-choice-small.png" style="display: block; margin: 0 auto;"></p>
+
+<h2 id="Оператор_if_..._else">Оператор if ... else</h2>
+
+<p>Давайте глянем на наиболее распространенный тип условного оператора, который вы будете использовать в JavaScript — <code><a href="/ru/docs/Web/JavaScript/Reference/Statements/if...else">if ... else</a></code><a href="/ru/docs/Web/JavaScript/Reference/Statements/if...else"> оператор</a>.</p>
+
+<h3 id="Базовый_if_..._else_синтаксис">Базовый if ... else синтаксис</h3>
+
+<p>Базовый <code>if...else</code> синтаксис выглядит как {{glossary("pseudocode")}}:</p>
+
+<pre class="notranslate">if (condition) {
+ code to run if condition is true
+} else {
+ run some other code instead
+}</pre>
+
+<p>Что мы имеем:</p>
+
+<ol>
+ <li>Ключевое слово <code>if</code> расположено перед круглыми скобками.</li>
+ <li>Условие для проверки (condition), расположено внутри круглых скобок (например "это значение больше другого значения?", или "это значение существует?"). Это условие использует операторы сравнения (<a href="/en-US/Learn/JavaScript/First_steps/Math#Comparison_operators">comparison operators</a>), которые мы изучим позже, и возвратит нам <code>true</code> или <code>false</code>.</li>
+ <li>Внутри скобок { } расположен код, который будет выполняться только в том случае, если условие (condition) верно (<code>true)</code>.</li>
+ <li>Ключевое слово <code>else (иначе)</code>.</li>
+ <li>Еще скобки { }, код внутри которых выполнится, только если условие не верно (не <code>true)</code>.</li>
+</ol>
+
+<p>Этот код довольно читабелен — он говорит "<strong>if (если)</strong>  <strong>condition (условие) </strong>возвращает <code>true (истина)</code>, запусти код A, <strong>else (иначе) </strong>запусти B"</p>
+
+<p>Стоит заметить, что  <code>else</code> и второй блок скобок { } не обязателен — следующий код так же будет работать:</p>
+
+<pre class="notranslate">if (condition) {
+ код, который должен выполнить, если условие истина
+}
+
+какой-то другой код</pre>
+
+<p>Тем не менее, следует быть осторожным — в случае, если код внутри вторых скобок { } не контролируется условием, то этот код будет выполняться <strong>всегда</strong>. Это не плохо, просто вы должны помнить об этом, чаще вы хотите запустить один кусок кода <em>или </em>другой, но не оба.</p>
+
+<p>И, наконец, иногда вы можете встретить код <code>if...else</code> без фигурных скобок в сокращенной форме:</p>
+
+<pre class="notranslate">if (condition) code to run if condition is true
+else run some other code instead</pre>
+
+<p>Это абсолютно рабочий код, но он менее читаем, лучше использовать фигурные скобки, новые строки и отступы.</p>
+
+<h3 id="Реальный_пример">Реальный пример</h3>
+
+<p>Чтобы лучше понять синтаксис, давайте рассмотрим реальный пример. Представьте, что мать или отец попросили помочь с работой по дому своего ребенка.  Родитель может сказать: "Если ты поможешь мне с покупками, то я дам тебе дополнительные деньги на карманные расходы, которые ты сможешь потратить на игрушку, какую захочешь".  В JavaScript, мы можем представить это так: </p>
+
+<pre class="brush: js notranslate">var shoppingDone = false;
+
+if (shoppingDone === true) {
+ var childsAllowance = 10;
+} else {
+ var childsAllowance = 5;
+}</pre>
+
+<p>В этом коде, как показано, всегда будет <code>shoppingDone</code> равный <code>false</code>, что означает разочарование для нашего бедного ребенка. Мы должны предоставить механизм для родителя, чтобы установить для переменной <code>shoppingDone</code> значение  <code>true</code> , если ребенок помог с покупками.</p>
+
+<div class="note">
+<p><strong>Примечание</strong>: Вы можете увидеть больше в <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/allowance-updater.html">полной версии этого примера на GitHub</a> (также посмотреть как он <a href="http://mdn.github.io/learning-area/javascript/building-blocks/allowance-updater.html">работает вживую</a>.)</p>
+</div>
+
+<h3 id="else_if">else if</h3>
+
+<p>В предыдущем примере предоставлено два выбора, или результата — но что, если мы хотим больше, чем два?</p>
+
+<p>Существует способ привязать дополнительные варианты/результаты к вашему <code>if...else</code> — использовать<code>else if</code>. Для каждого дополнительного выбора требуется дополнительный блок, который нужно расположить между <code>if() { ... }</code> и <code>else { ... }</code> — проверьте следующий более сложный пример, который может быть частью простого приложения прогноза погоды:</p>
+
+<pre class="brush: html notranslate">&lt;label for="weather"&gt;Выберите тип погоды сегодня: &lt;/label&gt;
+&lt;select id="weather"&gt;
+ &lt;option value=""&gt;--Сделайте выбор--&lt;/option&gt;
+ &lt;option value="sunny"&gt;Солнечно&lt;/option&gt;
+ &lt;option value="rainy"&gt;Дождливо&lt;/option&gt;
+ &lt;option value="snowing"&gt;Снежно&lt;/option&gt;
+ &lt;option value="overcast"&gt;Облачно&lt;/option&gt;
+&lt;/select&gt;
+
+&lt;p&gt;&lt;/p&gt;</pre>
+
+<pre class="brush: js notranslate">var select = document.querySelector('select');
+var para = document.querySelector('p');
+
+select.addEventListener('change', setWeather);
+
+function setWeather() {
+ var choice = select.value;
+
+ if (choice === 'sunny') {
+ para.textContent = 'Сегодня хорошо и солнечно. Носите шорты! Идите на пляж, или в парк, и купите мороженое.';
+ } else if (choice === 'rainy') {
+ para.textContent = 'Дождь падает за окном; возьмите плащ и зонт, и не находитесь слишком долго на улице.';
+ } else if (choice === 'snowing') {
+ para.textContent = 'Снег падает - морозно! Лучше всего посидеть с чашкой горячего шоколада или слепить снеговика.';
+ } else if (choice === 'overcast') {
+ para.textContent = 'Дождя нет, но небо серое и мрачное; он все может измениться в любую минуту, поэтому на всякий случай возьмите дождевик.';
+ } else {
+ para.textContent = '';
+ }
+}
+
+</pre>
+
+<p>{{ EmbedLiveSample('else_if', '100%', 100) }}</p>
+
+<ol>
+ <li>Здесь у нас есть элемент HTML {{htmlelement("select")}} который позволяет нам выбирать разные варианты погоды и простой абзац.</li>
+ <li>В JavaScript, мы создаем ссылки на элементы {{htmlelement("select")}} и {{htmlelement("p")}}, и добавляем обработчик события для элемента <code>&lt;select&gt;</code> , чтобы при изменении его значения, запускалась функция <code>setWeather()</code>.</li>
+ <li>Когда функция будет запущена, первоначально мы определим значение переменной <code>choice</code>, которая равна выбранному значению в элементе  <code>&lt;select&gt;</code>. Затем мы используем условный оператор для отображения текста внутри абзаца в зависимости от того, какое значение у переменной  <code>choice</code>. Обратите внимание, как все условия проверяются в <code>else if() {...}</code> блоках, за исключением первого, который использует <code>if() {...}</code>блок.</li>
+ <li>Последний выбор, внутри  <code>else {...}</code> блока, в основном является «последним средством» — код внутри него будет запущен, если ни одно из условий не будет <code>true</code>. В этом случае он служит для удаления текста из абзаца, если ничего не выбрано, например, если пользователь решает повторно выбрать опцию "--Сделайте выбор--" которая указана в начале.</li>
+</ol>
+
+<div class="note">
+<p><strong>Примечание</strong>: Вы можете <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/simple-else-if.html">найти этот пример на GitHub</a> (также <a href="http://mdn.github.io/learning-area/javascript/building-blocks/simple-else-if.html">увидеть как он работает</a>)</p>
+</div>
+
+<h3 id="Примечание_об_операторах_сравнения">Примечание об операторах сравнения</h3>
+
+<p>Операторы сравнения используют для проверки условий внутри наших условных операторов. Сначала мы посмотрели на операторы сравнения в  нашей статье <a href="/ru/docs/Learn/JavaScript/Первые_шаги/Math#Comparison_operators">Базовая математика в JavaScript — цифры и операторы</a> . Наш выбор это:</p>
+
+<ul>
+ <li><code>===</code> и <code>!==</code> — проверяет одно значение идентично или не идентично другому.</li>
+ <li><code>&lt;</code> и <code>&gt;</code> — проверяет одно значение меньше или больше, чем другое.</li>
+ <li><code>&lt;=</code> и <code>&gt;=</code> — проверяет одно значение меньше или равно, либо больше или равно другому.</li>
+</ul>
+
+<div class="note">
+<p><strong>Примечание</strong>: Просмотрите материал по предыдущей ссылке, если вы хотите освежить свою память.</p>
+</div>
+
+<p>Мы хотели бы особо обратить внимание на проверку булевых значений (<code>true</code>/<code>false</code>),  и общий шаблон, который вы будете встречать снова и снова. Любое значение, которое не есть  <code>false</code>, <code>undefined</code>, <code>null</code>, <code>0</code>, <code>NaN</code>, или пустая строка (<code>''</code>) фактически возвращает <code>true</code> при тестировании как условного оператора. Поэтому вы можете просто использовать имя собственной переменной, чтобы проверить, равна ли она <code>true</code>, или существует (т. е. переменная не равна undefined). Например:</p>
+
+<pre class="brush: js notranslate">var cheese = 'Cheddar';
+
+if (cheese) {
+ console.log('Ура! Есть сыр для приготовления бутерброда.');
+} else {
+ console.log('Сегодня нет сыра для бутерброда.');
+}</pre>
+
+<p>И, возвращаясь к нашему предыдущему примеру о ребенке, выполняющем поручение своего родителя, вы можете это записать так:</p>
+
+<pre class="brush: js notranslate">var shoppingDone = false;
+
+if (shoppingDone) { // не нужно явно указывать '=== true'
+ var childsAllowance = 10;
+} else {
+ var childsAllowance = 5;
+}</pre>
+
+<h3 id="Вложенность_if_..._else">Вложенность if ... else</h3>
+
+<p>Вполне нормально использовать один условный оператор <code>if...else</code> внутри другого — вложить их. Например, мы могли бы обновить наше приложение прогноза погоды, чтобы показать еще один набор вариантов в зависимости от температуры:</p>
+
+<pre class="brush: js notranslate">if (choice === 'sunny') {
+ if (temperature &lt; 86) {
+ para.textContent = 'Сейчас ' + temperature + ' градусов по фаренгейту — хорошо и солнечно. Идите на пляж, или в парк, и купите мороженое.';
+ } else if (temperature &gt;= 86) {
+ para.textContent = 'Сейчас ' + temperature + ' градусов по фаренгейту — Жара! Если вы хотите выйти на улицу, обязательно используйте солнцезащитный крем.';
+ }
+}</pre>
+
+<p>Несмотря на то, что весь код работает вместе, каждый условный оператор <code>if...else</code> работает полностью отдельно от другого.</p>
+
+<h3 id="Логические_операторы_И_ИЛИ_и_НЕ">Логические операторы: И, ИЛИ и НЕ</h3>
+
+<p>Если Вы хотите проверить несколько условий без записи вложенных <code>if...else</code> условий, <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators">логические операторы</a> помогут Вам. При использовании в условиях, первые два оператора делают следующее:</p>
+
+<ul>
+ <li><code>&amp;&amp;</code> — И; позволяет объединить два или более выражения так, что каждое из них отдельно должно иметь значение <code>true</code> , чтобы в итоге общее выражение имело значение <code>true</code>.</li>
+ <li><code>||</code> — ИЛИ; позволяет объединить два или более выражения так, что одно или несколько из них должно иметь значение <code>true</code> , чтобы в итоге общее выражение имело значение<code>true</code>.</li>
+</ul>
+
+<p>Чтобы дать вам пример оператора И, предыдущий фрагмент кода можно переписать так:</p>
+
+<pre class="brush: js notranslate">if (choice === 'sunny' &amp;&amp; temperature &lt; 86) {
+ para.textContent = 'Сейчас ' + temperature + ' градусов по фаренгейту — хорошо и солнечно. Идите на пляж, или в парк, и купите мороженое.';
+} else if (choice === 'sunny' &amp;&amp; temperature &gt;= 86) {
+ para.textContent = 'Сейчас ' + temperature + ' градусов по фаренгейту — Жара! Если вы хотите выйти на улицу, обязательно используйте солнцезащитный крем.';
+}</pre>
+
+<p>Так, для примера, первый блок кода выполнится только в том случае, если  <code>choice === 'sunny'</code> <em>и</em><code>temperature &lt; 86</code> вернут значение <code>true</code>.</p>
+
+<p>Давайте посмотрим на быстрый пример оператора ИЛИ:</p>
+
+<pre class="brush: js notranslate">if (iceCreamVanOutside || houseStatus === 'в огне') {
+ //если подъехал фургон с мороженым или дом горит
+  console.log('Вы должны быстро покинуть дом.');
+} else {
+ console.log('Вероятно, можно в нем оставаться.');
+}</pre>
+
+<p>Последний тип логического оператора НЕ, выраженный <code>!</code> оператором, можно использовать для отрицания выражения. Давайте объединим его с ИЛИ в приведенном выше примере:</p>
+
+<pre class="brush: js notranslate">if (!(iceCreamVanOutside || houseStatus === 'on fire')) {
+ console.log('Вероятно, можно в нем оставаться.');
+} else {
+ console.log('Вы должны быстро покинуть дом.');
+}</pre>
+
+<p>В этом фрагменте, если условие ИЛИ возвращает <code>true</code>, оператор НЕ будет отрицать это и выражение вернет <code>false</code>.</p>
+
+<p>Можно сочетать любое количество логических операторов, в любой последовательности и в любой комбинации. В следующем примере код в блоке будет выполняться только в том случае, если оба условия с ИЛИ возвращают true, а следовательно, и оператор И возвращает true:</p>
+
+<pre class="brush: js notranslate">if ((x === 5 || y &gt; 3 || z &lt;= 10) &amp;&amp; (loggedIn || userName === 'Steve')) {
+ // код выполняется
+}</pre>
+
+<p>Распространенной ошибкой при использовании логического оператора ИЛИ в условном выражении является указание переменной, значение которой нужно проверить со списком возможных значений этой переменной, разделенных операторами <code>||</code> (ИЛИ). Например.</p>
+
+<pre class="example-bad brush: js notranslate">if (x === 5 || 7 || 10 || 20) {
+ // выполнить код
+}</pre>
+
+<p>В данном примере условие в <code>if(...)</code>  всегда будет оцениваться как true, поскольку 7 (или любое другое ненулевое значение) всегда будет оцениваться как true. Фактически, это условие гласит «если х равен 5, или 7 является true». Но нам требуется совсем не это. Чтобы достичь нужной цели, придется выполнять полноценную проверку после каждого оператора ИЛИ:</p>
+
+<pre class="brush: js notranslate">if (x === 5 || x === 7 || x === 10 ||x === 20) {
+ // выполнить код
+}</pre>
+
+<h2 id="Оператор_switch">Оператор switch</h2>
+
+<p>Выражения <code>if...else</code> отлично справляются с добавлением условного кода, однако они не лишены недостатков. Они хорошо подходят для ситуации, когда имеется всего пара вариантов развития событий, каждый из которых имеет блок с приемлемым количеством кода, а также в случаях, когда условие является довольно сложным и включает несколько логических операторов. Если же нам требуется всего лишь задать переменную для определенного выбранного значения или напечатать конкретную фразу при определенном условии, изученный нами синтаксис может оказаться довольно громоздким, особенно если имеется большое количество вариантов выбора.</p>
+
+<p>В этом случае нам поможет <a href="/en-US/docs/Web/JavaScript/Reference/Statements/switch">оператор <code>switch</code> </a>– он принимает одно единственное выражение или значение, а затем просматривает ряд вариантов, пока не найдут вариант, соответствующий этому значению, после чего выполняет код, назначенный этому варианту. Вот пример использования этого оператора:</p>
+
+<pre class="notranslate">switch (выражение) {
+ case choice1:
+ выполнить этот код
+ break;
+
+ case choice2:
+ выполнить этот код, а не предыдущий
+ break;
+
+ // вариантов может быть любое количество
+
+ default:
+ а вообще-то, выполнить только этот код
+}</pre>
+
+<p>Что мы имеем:</p>
+
+<ol>
+ <li>Ключевое слово <code>switch</code>, за которым следует пара круглых скобок.</li>
+ <li>В скобках приводится выражение или значение.</li>
+ <li>Ключевое слово <code>case</code>, за которым следует вариант выбора (именно он проверяется на соответствие выражению или значению) и двоеточие.</li>
+ <li>Код, который будет выполняться, если вариант совпадает с выражением.</li>
+ <li>Оператор <code>break</code>, за которым следует точка с запятой. Если вариант совпал с выражением или значением, браузер закончит выполнять блок кода, дойдя до оператора <code>break</code>, и перейдет к выполнению кода, расположенного после оператора switch.</li>
+ <li>Вариантов выбора (пункты 3–5) может быть сколь угодно много.</li>
+ <li>Ключевое слово <code>default</code> используется точно также, как любой другой вариант выбора (пункты 3–5) за тем исключением, что после <code>default</code> нет других вариантов выбора, поэтому инструкция <code>break</code> не требуется, никакого кода дальше нет. Это вариант выбора по умолчанию, выбираемый, если ни один из других вариантов не совпал с выражением.</li>
+</ol>
+
+<div class="note">
+<p><strong>Примечание.</strong> Вариант выбора <code>default</code> может быть пропущен, если выражение гарантированно совпадет с одним из вариантов выбора. В противном случае вариант <code>default</code> необходим.</p>
+</div>
+
+<h3 id="Пример_оператора_switch">Пример оператора switch</h3>
+
+<p>Давайте рассмотрим реальный пример — перепишем наше приложение прогноза погоды с использованием оператора switch:</p>
+
+<pre class="brush: html notranslate">&lt;label for="weather"&gt;Выберите тип погоды сегодня: &lt;/label&gt;
+&lt;select id="weather"&gt;
+ &lt;option value=""&gt;--Сделайте выбор--&lt;/option&gt;
+ &lt;option value="sunny"&gt;Солнечно&lt;/option&gt;
+ &lt;option value="rainy"&gt;Дождливо&lt;/option&gt;
+ &lt;option value="snowing"&gt;Снежно&lt;/option&gt;
+ &lt;option value="overcast"&gt;Облачно&lt;/option&gt;
+&lt;/select&gt;
+
+&lt;p&gt;&lt;/p&gt;</pre>
+
+<pre class="brush: js notranslate">var select = document.querySelector('select');
+var para = document.querySelector('p');
+
+select.addEventListener('change', setWeather);
+
+
+function setWeather() {
+ var choice = select.value;
+
+ switch (choice) {
+ case 'sunny':
+ para.textContent = 'Сегодня хорошо и солнечно. Наденьте шорты! Идите на пляж или в парк, и купите мороженое.';
+ break;
+ case 'rainy':
+ para.textContent = 'На улице дождь. Возьмите плащ и зонт, и не гуляйте слишком долго';
+ break;
+ case 'snowing':
+ para.textContent = 'Идет снег - морозно! Лучше всего посидеть с чашкой горячего шоколада или слепить снеговика.';
+ break;
+ case 'overcast':
+ para.textContent = 'Дождя нет, но небо серое и мрачное; он все может измениться в любую минуту, поэтому на всякий случай возьмите дождевик.';
+ break;
+ default:
+ para.textContent = '';
+ }
+}</pre>
+
+<p>{{ EmbedLiveSample('Пример_оператора_switch', '100%', 100) }}</p>
+
+<div class="note">
+<p><strong>Note</strong>: Вы можете <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/simple-switch.html">найти этот пример на GitHub</a> (также увидеть <a href="http://mdn.github.io/learning-area/javascript/building-blocks/simple-switch.html">как он работает</a>.)</p>
+</div>
+
+<h2 id="Тернарный_оператор">Тернарный оператор</h2>
+
+<p>Это последний теоретический раздел данной статьи и мы перейдем к практическим упражнениям. <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator">Тернарный или условный оператор</a> имеет простой синтаксис: он проверяет условие и возвращает одно значение или выражение, если условие является <code>true</code>, и другое значение/выражение, если условие является <code>false</code>. Часто это очень удобная альтернатива блоку <code>if...else</code>, позволяющая затрачивать меньшие усилия на написание кода, когда имеется всего лишь два варианта, выбираемых на основе условия <code>true</code>/<code>false</code>. Общая схема оператора:</p>
+
+<pre class="notranslate">( условие) ? выполнить этот код : выполнить этот код вместо первого</pre>
+
+<p>Приведем простой пример:</p>
+
+<pre class="brush: js notranslate">var greeting = ( isBirthday ) ? 'С днем рождения, г-н Кузнецов! Хорошо Вам повеселиться!' : 'Доброе утро, г-н Кузнецов.';</pre>
+
+<p>У нас есть переменная <code>isBirthday</code> , если она <code>true</code>, мы отправляем посетителю поздравление с днем рождения; если нет – выдаем стандартное приветствие.</p>
+
+<h3 id="Пример_тернарного_оператора">Пример тернарного оператора</h3>
+
+<p>При использовании тернарного оператора не обязательно ограничиваться лишь значениями переменной, можно выполнять функции или строки кода; все, что угодно. В следующем примере показано простое средство выбора темы, задающее внешний вид веб-сайта с помощью тернарного оператора.</p>
+
+<pre class="brush: html notranslate">&lt;label for="theme"&gt;Выберите тему: &lt;/label&gt;
+&lt;select id="theme"&gt;
+ &lt;option value="white"&gt;Белая&lt;/option&gt;
+ &lt;option value="black"&gt;Черная&lt;/option&gt;
+&lt;/select&gt;
+
+&lt;h1&gt;Это мой веб-сайт&lt;/h1&gt;</pre>
+
+<pre class="brush: js notranslate">var select = document.querySelector('select');
+var html = document.querySelector('html');
+document.body.style.padding = '10px';
+
+function update(bgColor, textColor) {
+ html.style.backgroundColor = bgColor;
+ html.style.color = textColor;
+}
+
+select.onchange = function() {
+ ( select.value === 'black' ) ? update('black','white') : update('white','black');
+}
+</pre>
+
+<p>{{ EmbedLiveSample('Пример_тернарного_оператора', '100%', 300) }}</p>
+
+<p>Мы используем элемент {{htmlelement('select')}} для выбора темы (черная или белая), а также простой {{htmlelement('h1')}} для отображения заголовка веб-сайта. Кроме того, у нас есть функция <code>update()</code>, принимающая в качестве параметров (входных данных) два цвета. В качестве фона используется первый переданный цвет, а в качестве цвета текста – второй переданный цвет.</p>
+
+<p>Наконец, у нас есть слушатель событий <a href="/en-US/docs/Web/API/GlobalEventHandlers/onchange">onchange</a> , использующийся для запуска функции, содержащей тернарный оператор. Сначала она проверяет условие — <code>select.value === 'black'</code>. Если возвращается <code>true</code>, мы запускаем функцию <code>update()</code> с параметрами черного и белого, в результате чего получаем черный цвет фона и белый цвет текста. Если возвращается <code>false</code>, мы запускаем функцию <code>update()</code> с параметрами белого и черного, в результате чего цвета веб-сайта меняются на противоположные.</p>
+
+<div class="note">
+<p><strong>Note</strong>: Вы можете <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/simple-ternary.html">найти этот пример на GitHub</a> (также увидеть <a href="http://mdn.github.io/learning-area/javascript/building-blocks/simple-ternary.html">как он работает</a>.)</p>
+</div>
+
+<h2 id="Практическое_упражнение_простой_календарь">Практическое упражнение: простой календарь</h2>
+
+<p>В данном примере вы поможете нам закончить простое приложение календаря. Код включает:</p>
+
+<ul>
+ <li>Элемент {{htmlelement("select")}}, позволяющий пользователю выбирать разные месяцы.</li>
+ <li>Обработчик событий <code>onchange</code> для обнаружения изменения значения, выбранного в меню <code>&lt;select&gt;</code>.</li>
+ <li>Функция <code>createCalendar()</code> , рисующая календарь и отображающая правильный месяц в элементе {{htmlelement("h1")}}.</li>
+</ul>
+
+<p>Вы должны написать условную конструкцию в функции обработчика <code>onchange</code> , сразу после комментария <code>// ДОБАВЬТЕ СЮДА УСЛОВНОЕ ВЫРАЖЕНИЕ</code>. Конструкция должна:</p>
+
+<ol>
+ <li>Проверить выбранный месяц (хранящийся в переменной <code>choice</code>. Это будет значение элемента <code>&lt;select&gt;</code> после изменения значения, например, "Январь".)</li>
+ <li>Задать переменную, скажем, <code>days</code>, равную количеству дней в выбранном месяце. Для этого нужно будет проверить количество дней в каждом месяце. Високосный год можно не учитывать.</li>
+</ol>
+
+<p>Советы:</p>
+
+<ul>
+ <li>Советуем использовать логический оператор OR для группировки нескольких месяцев в рамках одного условия; многие месяцы имеют одинаковое количество дней.</li>
+ <li>Подумайте, какое количество дней в месяце встречается чаще всего и используйте его в качестве варианта по умолчанию.</li>
+</ul>
+
+<p>Если допустили ошибку, используйте кнопку «Сброс», чтобы вернуться к исходному виду примера. Если у вас совсем ничего не получается, нажмите «Показать решение».</p>
+
+<div class="blockIndicator note">
+<p>В HTML коде внутри <code>&lt;select&gt;</code> названия месяцев <code>value=""</code> введены на русском языке. Соответственно ссылки на них из вашего скрипта так же на русском. Не забываем про синтаксис. (прим. - <a href="/ru/profiles/ConstantineZz">ConstantineZz</a>)</p>
+</div>
+
+<div class="hidden">
+<h6 id="Playable_code">Playable code</h6>
+
+<pre class="brush: html notranslate">&lt;h2&gt;Live output&lt;/h2&gt;
+&lt;div class="output" style="height: 500px;overflow: auto;"&gt;
+&lt;label for="month"&gt;Выберите месяц: &lt;/label&gt;
+&lt;select id="month"&gt;
+&lt;option value="Январь"&gt;Январь&lt;/option&gt;
+&lt;option value="Февраль"&gt;Февраль&lt;/option&gt;
+&lt;option value="Март"&gt;Март&lt;/option&gt;
+&lt;option value="Апрель"&gt;Апрель&lt;/option&gt;
+&lt;option value="Май"&gt;Май&lt;/option&gt;
+&lt;option value="Июнь"&gt;Июнь&lt;/option&gt;
+&lt;option value="Июль"&gt;Июль&lt;/option&gt;
+&lt;option value="Август"&gt;Август&lt;/option&gt;
+&lt;option value="Сентябрь"&gt;Сентябрь&lt;/option&gt;
+&lt;option value="Октябрь"&gt;Октябрь&lt;/option&gt;
+&lt;option value="Ноябрь"&gt;Ноябрь&lt;/option&gt;
+&lt;option value="Декабрь"&gt;Декабрь&lt;/option&gt;
+&lt;/select&gt;
+&lt;h1&gt;&lt;/h1&gt;
+&lt;ul&gt;&lt;/ul&gt; &lt;/div&gt;
+
+&lt;h2&gt;Editable code&lt;/h2&gt;
+
+&lt;p class="a11y-label"&gt;Press Esc to move focus away from the code area (Tab inserts a tab character).&lt;/p&gt;
+
+&lt;textarea id="code" class="playable-code" style="height: 400px;width: 95%"&gt;
+var select = document.querySelector('select');
+var list = document.querySelector('ul');
+var h1 = document.querySelector('h1');
+
+select.onchange = function() {
+  var choice = select.value;
+
+  // <code>ДОБАВЬТЕ СЮДА УСЛОВНОЕ ВЫРАЖЕНИЕ</code>
+
+ createCalendar(days, choice);
+}
+
+function createCalendar(days, choice) {
+  list.innerHTML = '';
+  h1.textContent = choice;
+ for (var i = 1; i &lt;= days; i++) {
+  var listItem = document.createElement('li');
+ listItem.textContent = i;
+  list.appendChild(listItem);
+  }
+}
+
+createCalendar(31,'Январь');
+&lt;/textarea&gt;
+
+&lt;div class="playable-buttons"&gt;
+ &lt;input id="reset" type="button" value="Сброс"&gt;
+ &lt;input id="solution" type="button" value="Показать решение"&gt;
+&lt;/div&gt;</pre>
+
+<pre class="brush: css notranslate">.output * {
+ box-sizing: border-box;
+}
+
+.output ul {
+ padding-left: 0;
+}
+
+.output li {
+ display: block;
+ float: left;
+ width: 25%;
+ border: 2px solid white;
+ padding: 5px;
+ height: 40px;
+ background-color: #4A2DB6;
+ color: white;
+}
+
+html {
+ font-family: sans-serif;
+}
+
+h2 {
+ font-size: 16px;
+}
+
+.a11y-label {
+ margin: 0;
+ text-align: right;
+ font-size: 0.7rem;
+ width: 98%;
+}
+
+body {
+ margin: 10px;
+ background: #f5f9fa;
+}</pre>
+
+<pre class="brush: js notranslate">var textarea = document.getElementById('code');
+var reset = document.getElementById('reset');
+var solution = document.getElementById('solution');
+var code = textarea.value;
+var userEntry = textarea.value;
+
+function updateCode() {
+ eval(textarea.value);
+}
+
+reset.addEventListener('click', function() {
+ textarea.value = code;
+ userEntry = textarea.value;
+ solutionEntry = jsSolution;
+ solution.value = 'Показать решение';
+ updateCode();
+});
+
+solution.addEventListener('click', function() {
+ if(solution.value === 'Показать решение') {
+ textarea.value = solutionEntry;
+ solution.value = 'Скрыть решение';
+ } else {
+ textarea.value = userEntry;
+ solution.value = 'Показать решение';
+ }
+ updateCode();
+});
+
+var jsSolution = 'var select = document.querySelector(\'select\');\nvar list = document.querySelector(\'ul\');\nvar h1 = document.querySelector(\'h1\');\n\nselect.onchange = function() {\n var choice = select.value;\n var days = 31;\n if(choice === \'Февраль\') {\n days = 28;\n } else if(choice === \'Апрель\' || choice === \'Июнь\' || choice === \'Сентябрь\'|| choice === \'Ноябрь\') {\n days = 30;\n }\n\n createCalendar(days, choice);\n}\n\nfunction createCalendar(days, choice) {\n list.innerHTML = \'\';\n h1.textContent = choice;\n for(var i = 1; i &lt;= days; i++) {\n var listItem = document.createElement(\'li\');\n listItem.textContent = i;\n list.appendChild(listItem);\n }\n }\n\ncreateCalendar(31,\'Январь\');';
+var solutionEntry = jsSolution;
+
+textarea.addEventListener('input', updateCode);
+window.addEventListener('load', updateCode);
+
+// stop tab key tabbing out of textarea and
+// make it write a tab at the caret position instead
+
+textarea.onkeydown = function(e){
+ if (e.keyCode === 9) {
+ e.preventDefault();
+ insertAtCaret('\t');
+ }
+
+ if (e.keyCode === 27) {
+ textarea.blur();
+ }
+};
+
+function insertAtCaret(text) {
+ var scrollPos = textarea.scrollTop;
+ var caretPos = textarea.selectionStart;
+
+ var front = (textarea.value).substring(0, caretPos);
+ var back = (textarea.value).substring(textarea.selectionEnd, textarea.value.length);
+ textarea.value = front + text + back;
+ caretPos = caretPos + text.length;
+ textarea.selectionStart = caretPos;
+ textarea.selectionEnd = caretPos;
+ textarea.focus();
+ textarea.scrollTop = scrollPos;
+}
+
+// Update the saved userCode every time the user updates the text area code
+
+textarea.onkeyup = function(){
+ // We only want to save the state when the user code is being shown,
+ // not the solution, so that solution is not saved over the user code
+ if(solution.value === 'Показать решение') {
+ userEntry = textarea.value;
+ } else {
+ solutionEntry = textarea.value;
+ }
+
+ updateCode();
+};</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Playable_code', '100%', 1110) }}</p>
+
+<h2 id="Практическое_упражнение_расширяем_выбор_цветов">Практическое упражнение: расширяем выбор цветов</h2>
+
+<p>В данном примере вы будете использовать пример тернарного оператора, который мы рассматривали ранее, и превратите тернарный оператор в инструкцию switch, что позволит увеличить количество вариантов выбора для простого веб-сайта. Посмотрите на {{htmlelement("select")}} — на этот раз он включает не два, а целых пять вариантов тем. Нужно добавить инструкцию switch сразу под комментарием <code>// ДОБАВЬТЕ ИНСТРУКЦИЮ SWITCH</code>:</p>
+
+<ul>
+ <li>Она должна принимать переменную <code>choice</code> в качестве входного выражения.</li>
+ <li>Каждый элемент case должен содержать вариант выбора, соответствующий одному из доступных для выбора значений: белая, черная, лиловая, желтая или психоделическая тема.</li>
+ <li>В блоке каждого элемента case необходимо вызывать функцию <code>update()</code>, которой передается два цвета: первый – это цвет фона, а второй – цвет текста. Помните, что значения цветов – это строковые значения, поэтому их нужно заключать в кавычки.</li>
+</ul>
+
+<p>Если допустили ошибку, используйте кнопку «Сброс», чтобы вернуться к исходному виду примера. Если у вас совсем ничего не получается, нажмите «Показать решение».</p>
+
+<div class="hidden">
+<h6 id="Playable_code_2">Playable code 2</h6>
+
+<pre class="brush: html notranslate">&lt;div class="output" style="height: 300px;"&gt;
+ &lt;label for="theme"&gt;Выберите тему: &lt;/label&gt;
+ &lt;select id="theme"&gt;
+ &lt;option value="white"&gt;Белая&lt;/option&gt;
+ &lt;option value="black"&gt;Черная&lt;/option&gt;
+ &lt;option value="purple"&gt;Лиловая&lt;/option&gt;
+ &lt;option value="yellow"&gt;Желтая&lt;/option&gt;
+ &lt;option value="psychedelic"&gt;Психоделическая&lt;/option&gt;
+ &lt;/select&gt;
+
+ &lt;h1&gt;Это мой веб-сайт&lt;/h1&gt;
+&lt;/div&gt;
+
+&lt;hr&gt;
+
+&lt;textarea id="code" class="playable-code" style="height: 450px;"&gt;
+var select = document.querySelector('select');
+var html = document.querySelector('.output');
+
+select.onchange = function() {
+ var choice = select.value;
+
+ // ДОБАВЬТЕ ИНСТРУКЦИЮ SWITCH
+}
+
+function update(bgColor, textColor) {
+ html.style.backgroundColor = bgColor;
+ html.style.color = textColor;
+}&lt;/textarea&gt;
+
+&lt;div class="playable-buttons"&gt;
+ &lt;input id="reset" type="button" value="Сброс"&gt;
+ &lt;input id="solution" type="button" value="Показать решение"&gt;
+&lt;/div&gt;
+</pre>
+
+<pre class="brush: js notranslate">var textarea = document.getElementById('code');
+var reset = document.getElementById('reset');
+var solution = document.getElementById('solution');
+var code = textarea.value;
+
+function updateCode() {
+ eval(textarea.value);
+}
+
+reset.addEventListener('click', function() {
+ textarea.value = code;
+  userEntry = textarea.value;
+  solutionEntry = jsSolution;
+  solution.value = 'Показать решение';
+ updateCode();
+});
+
+solution.addEventListener('click', function() {
+ if(solution.value === 'Показать решение') {
+  textarea.value = solutionEntry;
+  solution.value = 'Скрыть решение';
+  } else {
+  textarea.value = userEntry;
+  solution.value = 'Показать решение';
+  }
+ updateCode();
+});
+
+var jsSolution = 'var select = document.querySelector(\'select\');\nvar html = document.querySelector(\'.output\');\n\nselect.onchange = function() {\n var choice = select.value;\n\n switch(choice) {\n case \'black\':\n update(\'black\',\'white\');\n break;\n case \'white\':\n update(\'white\',\'black\');\n break;\n case \'purple\':\n update(\'purple\',\'white\');\n break;\n case \'yellow\':\n update(\'yellow\',\'darkgray\');\n break;\n case \'psychedelic\':\n update(\'lime\',\'purple\');\n break;\n }\n}\n\nfunction update(bgColor, textColor) {\n html.style.backgroundColor = bgColor;\n html.style.color = textColor;\n}';
+var solutionEntry = jsSolution;
+
+textarea.addEventListener('input', updateCode);
+window.addEventListener('load', updateCode);
+
+// stop tab key tabbing out of textarea and
+// make it write a tab at the caret position instead
+
+textarea.onkeydown = function(e){
+  if (e.keyCode === 9) {
+  e.preventDefault();
+  insertAtCaret('\t');
+  }
+
+  if (e.keyCode === 27) {
+  textarea.blur();
+  }
+  };
+
+function insertAtCaret(text) {
+ var scrollPos = textarea.scrollTop;
+ var caretPos = textarea.selectionStart;
+
+  var front = (textarea.value).substring(0, caretPos);
+  var back = (textarea.value).substring(textarea.selectionEnd, textarea.value.length);
+  textarea.value = front + text + back;
+  caretPos = caretPos + text.length;
+  textarea.selectionStart = caretPos;
+  textarea.selectionEnd = caretPos;
+  textarea.focus();
+  textarea.scrollTop = scrollPos;
+ }
+
+// Update the saved userCode every time the user updates the text area code
+
+textarea.onkeyup = function(){
+  // We only want to save the state when the user code is being shown,
+  // not the solution, so that solution is not saved over the user code
+  if(solution.value === 'Показать решение') {
+  userEntry = textarea.value;
+  } else {
+  solutionEntry = textarea.value;
+  }
+
+
+updateCode();
+
+};
+
+</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Playable_code_2', '100%', 650) }}</p>
+
+<h2 id="Заключение">Заключение</h2>
+
+<p>Это все, что вам нужно знать на данный момент об условных логических структурах! Уверены, вы хорошо разобрались в теоретическом материале и с легкостью справились с предложенными упражнениями. Если же что-то осталось для вас непонятным, перечитайте статью еще раз или <a href="/en-US/Learn#Contact_us">свяжитесь с нами</a>.</p>
+
+<h2 id="См._также">См. также</h2>
+
+<ul>
+ <li><a href="/en-US/Learn/JavaScript/First_steps/Math#Comparison_operators">Comparison operators</a></li>
+ <li><a href="/en-US/docs/Web/JavaScript/Guide/Control_flow_and_error_handling#Conditional_statements">Conditional statements in detail</a></li>
+ <li><a href="/en-US/docs/Web/JavaScript/Reference/Statements/if...else">if...else reference</a></li>
+ <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator">Conditional (ternary) operator reference</a></li>
+</ul>
+
+<p>{{NextMenu("Learn/JavaScript/Building_blocks/Looping_code", "Learn/JavaScript/Building_blocks")}}</p>
diff --git a/files/ru/learn/javascript/building_blocks/functions/index.html b/files/ru/learn/javascript/building_blocks/functions/index.html
new file mode 100644
index 0000000000..b612858b42
--- /dev/null
+++ b/files/ru/learn/javascript/building_blocks/functions/index.html
@@ -0,0 +1,390 @@
+---
+title: Функции — Переиспользуемые блоки кода
+slug: Learn/JavaScript/Building_blocks/Functions
+tags:
+ - Функции
+ - аргументы
+ - методы
+ - параметры
+translation_of: Learn/JavaScript/Building_blocks/Functions
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Looping_code","Learn/JavaScript/Building_blocks/Build_your_own_function", "Learn/JavaScript/Building_blocks")}}</div>
+
+<p class="summary">Другая важная концепция в кодировании —  <strong>функции </strong>— позволяют хранить фрагмент кода, который выполняет одну задачу внутри определенного блока, а затем вызывать этот код всякий раз, когда вам это нужно, используя одну короткую команду, вместо того, чтобы вводить один и тот же код несколько раз.</p>
+
+<p class="summary">В этой статье мы рассмотрим фундаментальные концепции функций, такие как базовый синтаксис, способы вызова и их определения, область действия и параметры.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Предпосылки:</th>
+ <td>Начальная компьютерная грамотность, основы HTML и CSS, <a href="/ru/docs/Learn/JavaScript/First_steps">первые шаги JavaScript</a>.</td>
+ </tr>
+ <tr>
+ <th scope="row">Цель:</th>
+ <td>Понять фундаментальные основы функций языка JavaScript.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Где_можно_встретить_функции">Где можно встретить функции?</h2>
+
+<p>В JavaScript, Вы везде уведите функции. На самом деле, мы пользовались функциями на протяжении всего курса; только мы не говорили об этом слишком часто. Теперь наступило время, чтобы поговорить о функциях более конкретно и разобрать их синтаксис.</p>
+
+<p>В значительном количестве случаев, когда вы пользуетесь структурой JavaScript, в которой есть пара обычных скобок — <code>()</code> — и при этом, это не является структурой типа <a href="/ru/Learn/JavaScript/Building_blocks/Looping_code#The_standard_for_loop">цикл for </a>, <a href="/ru/Learn/JavaScript/Building_blocks/Looping_code#while_and_do_..._while">while, или do...while цикл</a>, или <a href="/ru/Learn/JavaScript/Building_blocks/conditionals#if_..._else_statements">if...else конструкция</a>, Вы используете функцию.</p>
+
+<h2 id="Встроенные_функции_браузера">Встроенные функции браузера</h2>
+
+<p>В этом курсе мы использовали функции, встроенные в браузер. Каждый раз, когда мы манипулировали текстовой строкой, например:</p>
+
+<pre class="brush: js notranslate">var myText = 'Я строка';
+var newString = myText.replace('строка', 'сосиска');
+console.log(newString);
+// Функция строки replace() принимает строку,
+// заменяет одну строку на другую, и возвращает
+// новую строку с замененным содержимым</pre>
+
+<p>Или каждый раз, когда мы манипулировали массивом:</p>
+
+<pre class="brush: js notranslate">var myArray = ['Я', 'люблю', 'шоколадных', 'лягушек'];
+var madeAString = myArray.join(' ');
+console.log(madeAString);
+// Функция join() принимает массив, соединяет
+// все элементы массива вместе в одну строку,
+// и возвращает эту новую строку</pre>
+
+<p>Или каждый раз, когда мы генерировали случайное число:</p>
+
+<pre class="brush: js notranslate">var myNumber = Math.random()
+// Функция random() генерирует случайное число от 0 до 1,
+// и возвращает это число</pre>
+
+<p>...мы использовали функции!</p>
+
+<div class="note">
+<p><strong>Примечание</strong>: Вы можете вставить эти строки в консоль вашего браузера, чтобы посмотреть, как работают эти функции.</p>
+</div>
+
+<p>Фактически, часть кода, который вы вызываете, когда ссылаетесь на встроенную функцию браузера  (воображаемое слово для её запуска или выполнения), не может быть написана на JavaScript — многие из этих функций вызывают части фонового кода браузера, который написан в основном на системных языках низкого уровня, таких как C ++, а не на веб-языках, таких как JavaScript.</p>
+
+<p>Имейте в виду, что некоторые встроенные функции браузера не являются частью основного языка JavaScript — некоторые из них являются частью API браузера, которые основываются на языке по умолчанию, чтобы обеспечить еще большую функциональность (подробнее см. <a href="/ru/docs/Learn/JavaScript/Первые_шаги/What_is_JavaScript#Так_что_же_он_действительно_может_делать">один из предыдущих разделов этого курса</a>). Более подробно рассмотрим использование API браузера в более позднем модуле курса.</p>
+
+<h2 id="Функции_или_методы">Функции или методы</h2>
+
+<p>Одну вещь, которую нам нужно прояснить, прежде чем двигаться дальше - технически, встроенные функции браузера не являются функциями — это <strong>методы</strong>. Это звучит немного страшно и запутанно, но не волнуйтесь — функции и методы слова во многом взаимозаменяемы, по крайней мере для наших целей, на данном этапе вашего обучения.</p>
+
+<p>Разница между методом и функцией лишь в том, что методы - это функции, определенные внутри объектов. Встроенные функции (методы) браузера и переменные (так называемые <strong>свойства</strong>) хранятся внутри структурированных объектов, чтобы сделать код более эффективным и более простым в использовании.</p>
+
+<p>Вам пока не нужно изучать внутреннюю работу структурированных объектов JavaScript - вы можете подождать, пока наш более поздний модуль не научит вас внутренним работам объектов и тому, как создавать свои собственные. На данный момент мы просто хотим устранить любую возможную путаницу метода, в сравнении с функциями - вы, вероятно, встретите оба термина, когда будете смотреть на доступные связанные ресурсы через Интернет.</p>
+
+<h2 id="Пользовательские_функции">Пользовательские функции</h2>
+
+<p>В этом курсе так же использовались <strong>пользовательские функции</strong> — это функции, которые вы определяете в своем коде, а не внутри браузера. Каждый раз, когда вы видели произвольное слово (имя функции) с круглыми скобками прямо после него, вы использовали пользовательскую функцию. В нашем примере <a href="http://mdn.github.io/learning-area/javascript/building-blocks/loops/random-canvas-circles.html">random-canvas-circles.html</a> (подробнее см. <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/random-canvas-circles.html">исходный код</a>) из нашей <a href="/ru/docs/Learn/JavaScript/Building_blocks/Looping_code">статьи о циклах</a> мы включили пользовательскую функцию <code>draw()</code>, которая выглядит так:</p>
+
+<pre class="brush: js notranslate">function draw() {
+ ctx.clearRect(0,0,WIDTH,HEIGHT);
+ for (var i = 0; i &lt; 100; i++) {
+ ctx.beginPath();
+ ctx.fillStyle = 'rgba(255,0,0,0.5)';
+ ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI);
+ ctx.fill();
+ }
+}</pre>
+
+<p>Эта функция рисует 100 случайных кругов внутри элемента {{htmlelement("canvas")}}. Каждый раз, когда мы хотим это сделать, мы можем вызвать эту функцию следующим образом</p>
+
+<pre class="brush: js notranslate">draw();</pre>
+
+<p>вместо того, чтобы каждый раз, когда мы хотим повторить этот код, не писать его заново. И функции могут содержать любой код, который вам нравится - вы можете даже вызывать другие функции внутри своих функций. Вышеупомянутая функция, например, вызывает функцию <code>random()</code> три раза, которая выглядит следующим образом:</p>
+
+<pre class="brush: js notranslate">function random(number) {
+ return Math.floor(Math.random()*number);
+}</pre>
+
+<p>Нам понадобилась эта функция, потому что встроенная в браузер функция <a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/Math/random">Math.random()</a> генерирует случайное дробное число от 0 до 1. Но мы хотим случайное целое число от 0 до указанного числа.</p>
+
+<h2 id="Вызов_функций">Вызов функций</h2>
+
+<p>Скорее всего, вы уже поняли это, но на всякий случай ... чтобы использовать функцию после того, как она была определена, вам нужно запустить или вызвать ее. Это делается путем включения имени функции в код где-нибудь, за которым следуют скобки.</p>
+
+<pre class="brush: js notranslate">function myFunction() {
+ alert('привет');
+}
+
+myFunction()
+// Единовременный вызов функции</pre>
+
+<h2 id="Безымянные_функции">Безымянные функции</h2>
+
+<p>Вы можете видеть функции, определенные и вызываемые несколькими разными способами. До этого мы создавали функции таким способом:</p>
+
+<pre class="brush: js notranslate">function myFunction() {
+ alert('привет');
+}</pre>
+
+<p>Но вы также можете создавать функции без имени:</p>
+
+<pre class="brush: js notranslate">function() {
+ alert('привет');
+}</pre>
+
+<p>Такая функция называется <strong>безымянная функция</strong> (или анонимная) — она не имеет имени! Она сама по себе ничего не делает. Обычно такие функции используются вместе с обработчиком событий, например, следующее будет вызывать код внутри функции каждый раз, по нажатию соответствующей кнопки:</p>
+
+<pre class="brush: js notranslate">var myButton = document.querySelector('button');
+
+myButton.onclick = function() {
+ alert('привет');
+}</pre>
+
+<p>В приведенном примере требуется, чтобы на странице был элемент {{htmlelement ("button")}} (кнопка), которую нужно нажать. Вы уже видели такую структуру несколько раз на протяжении всего курса, подробнее о ней вы узнаете из следующей статьи.</p>
+
+<p>Вы также можете присвоить к переменной анонимную функцию, например:</p>
+
+<pre class="brush: js notranslate">var myGreeting = function() {
+ alert('привет');
+}</pre>
+
+<p>Теперь эту функцию можно вызвать, используя:</p>
+
+<pre class="brush: js notranslate">myGreeting();</pre>
+
+<p>Фактически такой способ присваивает переменной имя; вы также можете присвоить функцию значением нескольких переменных, например:</p>
+
+<pre class="brush: js notranslate">var anotherGreeting = function() {
+ alert('привет');
+}</pre>
+
+<p>Теперь функцию можно вызвать, используя любую из переменных</p>
+
+<pre class="brush: js notranslate">myGreeting();
+anotherGreeting();</pre>
+
+<p>Но это может ввести в заблуждение, так что не стоит так делать! При создании функций лучше всего придерживаться следующего вида:</p>
+
+<pre class="brush: js notranslate">function myGreeting() {
+ alert('привет');
+}</pre>
+
+<p>Чаще всего вы будете использовать анонимные функции, чтобы просто запускать код при срабатывания события - например, нажатие кнопки - с помощью обработчика событий. Опять же, это выглядит примерно так:</p>
+
+<pre class="brush: js notranslate">myButton.onclick = function() {
+ alert('привет');
+ // При желании, внутри этой функции
+ // можно написать много кода.
+}</pre>
+
+<h2 id="Параметры_функции">Параметры функции</h2>
+
+<p>Некоторые функции при их вызове требуют указание параметров — это значения, которые должны быть вставлены в круглые скобки функции, необходимые для корректной работы функции.</p>
+
+<div class="note">
+<p><strong>Примечание</strong>: Параметры иногда называются аргументами, свойствами или атрибутами.</p>
+</div>
+
+<p>Например встроенная в браузер функция <a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/Math/random">Math.random()</a> не требует параметров. При вызове, она всегда возвращает случайное число от 0 до 1:</p>
+
+<pre class="brush: js notranslate">var myNumber = Math.random();</pre>
+
+<p>Браузерная встроенная функция, работающая со строкой, <a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/String/replace">replace()</a> ожидает два параметра — это подстрока для поиска в основной строке и строка, на которую происходит замена в основной строке:</p>
+
+<pre class="brush: js notranslate">var myText = 'Я строка';
+var newString = myText.replace('строка', 'сосиска');</pre>
+
+<div class="note">
+<p><strong>Примечание</strong>: Если необходимо указать несколько параметров, их разделяют запятыми.</p>
+</div>
+
+<p>Следует также отметить, что иногда параметры являются необязательными - вам не нужно их указывать. Если вы этого не сделаете, функция, как правило, примет какое-то поведение по умолчанию. В качестве примера параметр функции массива <a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/join">join()</a> необязателен:</p>
+
+<pre class="brush: js notranslate">var myArray = ['Я', 'люблю', 'шоколадных', 'лягушек'];
+var madeAString = myArray.join(' ');
+// Вернет 'Я люблю шоколадных лягушек'
+var madeAString = myArray.join();
+// Вернет 'Я,люблю,шоколадных,лягушек'</pre>
+
+<p>Если не указан параметр для символа соединения / разграничения, по умолчанию используется запятая.</p>
+
+<h2 id="Область_видимости_функции_и_конфликты">Область видимости функции и конфликты</h2>
+
+<p>Давайте немного поговорим о {{glossary("scope")}} - очень важная концепция при работе с функциями. Когда вы создаете функцию, переменные и другие вещи, определенные внутри функции, находятся внутри их отдельной <strong>области (scope)</strong>, что означает, что они заперты в своих отдельных отсеках, недоступных из других функций или из кода вне функций.</p>
+
+<p>Верхний уровень за пределами всех ваших функций называется <strong>глобальной областью (global scope)</strong>. Значения, определенные в глобальном масштабе, доступны извне в коде.</p>
+
+<p>JavaScript настроен таким образом по разным причинам - но главным образом из-за безопасности и организации. Иногда вы не хотите, чтобы переменные были доступны извне в коде - внешние скрипты, которые вы вызывали из других источников, могут начать работать с вашим кодом и вызывать проблемы, потому что они используют одни и те же имена переменных, как и другие части кода , вызывая конфликты. Это может быть сделано злонамеренно или просто случайно.</p>
+
+<p>Например, скажем, у вас есть файл HTML, который вызывается в двух внешних файлах JavaScript, и оба они имеют переменную и определенную функцию, которые используют одно и то же имя:</p>
+
+<pre class="brush: html notranslate">&lt;!-- Excerpt from my HTML --&gt;
+&lt;script src="first.js"&gt;&lt;/script&gt;
+&lt;script src="second.js"&gt;&lt;/script&gt;
+&lt;script&gt;
+ greeting();
+&lt;/script&gt;</pre>
+
+<pre class="brush: js notranslate">// first.js
+var name = 'Chris';
+function greeting() {
+ alert('Hello ' + name + ': welcome to our company.');
+}</pre>
+
+<pre class="brush: js notranslate">// second.js
+var name = 'Zaptec';
+function greeting() {
+ alert('Our company is called ' + name + '.');
+}</pre>
+
+<p>Обе функции, которые вы хотите вызвать, называются <code>greeting()</code>, но вы можете получить доступ только к функции <code>greeting()</code> файла <code>first.js</code> (функция файла <code>second.js</code> игнорируется). Кроме того, попытка объявить переменную <code>name</code> второй раз через <code>let</code> в файле <code>second.js</code> приведет к ошибке.</p>
+
+<div class="note">
+<p><strong>Примечание</strong>: Этот пример можно увидеть в режиме <a href="https://mdn.github.io/learning-area/javascript/building-blocks/functions/conflict.html">Live на GitHub</a> (см. также <a href="/ru/docs/https://github.com/mdn/learning-area/tree/master/javascript/building-blocks/functions">исходный код</a>).</p>
+</div>
+
+<p>Хранение частей вашего кода, заблокированных функциями, позволяет избежать таких проблем и считается наилучшей практикой.</p>
+
+<p>Это немного похоже на зоопарк. Львы, зебры, тигры и пингвины находятся в своих собственных ограждениях и имеют доступ только к вещам внутри их вольеров - таким же образом, как и в области функций. Если бы они смогли попасть в другие вольеры, возникли проблемы. В лучшем случае разные животные будут чувствовать себя неудобно в незнакомых местах обитания - лев или тигр будут чувствовать себя ужасно внутри водянистой, ледяной области пингвинов. В худшем случае львы и тигры могут попытаться съесть пингвинов!</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14079/MDN-mozilla-zoo.png" style="display: block; margin: 0 auto;"></p>
+
+<p>Хранитель зоопарка подобен глобальной переменной - он или она имеет ключи для доступа к каждому вольеру, для пополнения запасов пищи, ухода за больными животными и т. д.</p>
+
+<h3 id="Активное_обучение_игра_с_scope">Активное обучение: игра с scope</h3>
+
+<p>Давайте посмотрим на реальный пример, демонстрирующий обзор.</p>
+
+<ol>
+ <li>Сначала создайте локальную копию нашего примера <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/functions/function-scope.html">function-scope.html</a>. Это содержит две функции, называемые <code>a()</code> и <code>b()</code>, и три переменные - <code>x</code>, <code>y</code> и <code>z</code> - две из которых определены внутри функций и одна в глобальной области. Он также содержит третью функцию, называемую <code>output()</code>, которая принимает один параметр и выводит его в абзаце на странице.</li>
+ <li>Откройте пример в браузере и в текстовом редакторе.</li>
+ <li>Откройте консоль JavaScript в инструментах разработчика вашего браузера. В консоли JavaScript введите следующую команду:
+ <pre class="brush: js notranslate">output(x);</pre>
+ Вы должны увидеть значение переменной <code>x</code> вывод на экране.</li>
+ <li>Теперь попробуйте ввести следующее в консоли
+ <pre class="brush: js notranslate">output(y);
+output(z);</pre>
+ Оба из них должны возвращать ошибку в строке "<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Not_defined">ReferenceError: y is not defined</a>". Почему это? Из-за функции scope - <code>y</code> и <code>z</code> блокируются внутри функций <code>a() </code>и <code>b()</code>, поэтому <code>output()</code> не может получить к ним доступ при вызове из глобальной области.</li>
+ <li>Однако как насчет того, когда он вызван изнутри другой функции? Попробуйте отредактировать функции <code>a()</code> и <code>b()</code>, чтобы они выглядели следующим образом:
+ <pre class="brush: js notranslate">function a() {
+ var y = 2;
+ output(y);
+}
+
+function b() {
+ var z = 3;
+ output(z);
+}</pre>
+ Сохраните код и перезагрузите его в своем браузере, затем попробуйте вызвать функции <code>a()</code> и <code>b()</code> из консоли JavaScript:
+
+ <pre class="brush: js notranslate">a();
+b();</pre>
+ Вы должны увидеть значения y и z, выводимые на странице. Это отлично работает, так как функция <code>output() </code>вызывается внутри других функций - в той же области, где переменные, которые она печатает, определяются в каждом случае. <code>output()</code> доступен из любого места, поскольку он определен в глобальной области.</li>
+ <li>Теперь попробуйте обновить свой код следующим образом:
+ <pre class="brush: js notranslate">function a() {
+ var y = 2;
+ output(x);
+}
+
+function b() {
+ var z = 3;
+ output(x);
+}</pre>
+ Сохраните и перезагрузите снова и повторите попытку в консоли JavaScript:</li>
+ <li>
+ <pre class="brush: js notranslate"><code>a();
+b();</code></pre>
+
+ <p>Оба вызова <code>a()</code> и <code>b()</code> должны выводить значение x - 1. Они работают нормально, потому что, хотя вызовы <code>output()</code> не находятся в той же области, где определено <code>x</code>, <code>x</code> - глобальная переменная, поэтому она доступна внутри всего кода, везде</p>
+ </li>
+ <li>Наконец, попробуйте обновить свой код следующим образом:
+ <pre class="brush: js notranslate"><code>function a() {
+ var y = 2;
+ output(z);
+}
+
+function b() {
+ var z = 3;
+ output(y);
+}</code></pre>
+ Сохраните и перезагрузите снова и повторите попытку в консоли JavaScript:</li>
+ <li>
+ <pre class="brush: js notranslate"><code>a();
+b();</code></pre>
+ </li>
+</ol>
+
+<p>На этот раз вызовы <code>a()</code> и <code>b()</code> возвратят эту раздражающую ошибку "<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Not_defined">ReferenceError: z is not defined</a>" - это потому, что вызовы <code>output()</code> и переменные, которые они пытаются распечатать, не определены внутри одних и тех же областей функций - переменные эффективно невидимы для этих вызовов функций.</p>
+
+<div class="note">
+<p><strong>Примечание</strong>: Те же правила определения не применяются к циклу (например, <code>for() { ... }</code>) и условным блокам (например, <code>if() { ... }</code>) - они выглядят очень похожими, но это не одно и то же! Старайтесь не путать их.</p>
+</div>
+
+<div class="note">
+<p><strong>Примечание:</strong> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Not_defined">ReferenceError: "x" is not defined</a>. Ошибка - это одна из наиболее распространенных проблем, с которой вы столкнетесь. Если вы получите эту ошибку, и вы уверены, что определили эту переменную, проверьте, в какой области она находится.</p>
+</div>
+
+<ul>
+</ul>
+
+<h3 id="Функции_внутри_функций">Функции внутри функций</h3>
+
+<p>Имейте в виду, что вы можете вызывать функцию из любого места, даже если она внутри другой функции.  Это часто используется как способ поддержания чистоты кода. Если у вас есть большая сложная функция, ее легче понять, если разбить ее на несколько подфункций:</p>
+
+<pre class="brush: js notranslate">function myBigFunction() {
+ var myValue;
+
+ subFunction1();
+ subFunction2();
+ subFunction3();
+}
+
+function subFunction1() {
+ console.log(myValue);
+}
+
+function subFunction2() {
+ console.log(myValue);
+}
+
+function subFunction3() {
+ console.log(myValue);
+}
+</pre>
+
+<p>Просто убедитесь, что значения, используемые внутри функции, находятся в области видимости. В приведенном выше примере выдается ошибка <code>ReferenceError: MyValue is not defined</code>, поскольку хотя переменная <code>myValue</code> определена в той же области, что и вызовы функций, она не определена в определениях функций - фактический код, который запускается при вызове функций. Чтобы это работало, вам нужно передать значение в функцию в качестве параметра, например так:</p>
+
+<pre class="brush: js notranslate">function myBigFunction() {
+ var myValue = 1;
+
+ subFunction1(myValue);
+ subFunction2(myValue);
+ subFunction3(myValue);
+}
+
+function subFunction1(value) {
+ console.log(value);
+}
+
+function subFunction2(value) {
+ console.log(value);
+}
+
+function subFunction3(value) {
+ console.log(value);
+}</pre>
+
+<h2 id="Заключение">Заключение</h2>
+
+<p>В этой статье были рассмотрены основные понятия, лежащие в основе функций, позволяющие освоить следующий материал, в котором мы получим практические навыки, и научимся создавать собственные функции.</p>
+
+<h2 id="Смотрите_также">Смотрите также</h2>
+
+<ul>
+ <li><a href="/ru/docs/Web/JavaScript/Guide/Functions">Детальное руководство по функциям</a> — описание некоторых дополнительных функций, не описанных в этой статье.</li>
+ <li><a href="/ru/docs/Web/JavaScript/Reference/Functions">Описание функций</a></li>
+ <li><a href="/ru/docs/Web/JavaScript/Reference/Functions/Default_parameters">Параметры по умолчанию</a>, <a href="/ru/docs/Web/JavaScript/Reference/Functions/Arrow_functions">Стрелочные функции</a> — продвинутая документация</li>
+</ul>
+
+<ul>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Looping_code","Learn/JavaScript/Building_blocks/Build_your_own_function", "Learn/JavaScript/Building_blocks")}}</p>
diff --git a/files/ru/learn/javascript/building_blocks/image_gallery/index.html b/files/ru/learn/javascript/building_blocks/image_gallery/index.html
new file mode 100644
index 0000000000..a0e1e48cd5
--- /dev/null
+++ b/files/ru/learn/javascript/building_blocks/image_gallery/index.html
@@ -0,0 +1,146 @@
+---
+title: Фотогалерея
+slug: Learn/JavaScript/Building_blocks/Image_gallery
+tags:
+ - Обработчик событий
+ - Оценка
+ - начальный уровень
+ - события
+ - циклы
+translation_of: Learn/JavaScript/Building_blocks/Image_gallery
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenu("Learn/JavaScript/Building_blocks/Events", "Learn/JavaScript/Building_blocks")}}</div>
+
+<p class="summary">Теперь, после изучения основ JavaScript, мы проверим ваши знания циклов, функций, условных операторов и событий предложив вам написать популярный элемент который вы увидите на многих сайтах - галерея на JavaScript.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Необходимые знания:</th>
+ <td>
+ <p>Перед выполнением этого задания вы должны проработать все статьи в этом модуле.</p>
+ </td>
+ </tr>
+ <tr>
+ <th scope="row">Цель:</th>
+ <td>Проверить понимание циклов, функций, условных операторов и событий в JavaScript.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Отправная_точка">Отправная точка</h2>
+
+<p>Для начала скачайте <a href="https://github.com/ConstantineZz/learning-area/raw/master/javascript/building-blocks/gallery/gallery-start-rv.zip">ZIP файл</a> для примера и распакуйте его содержимое у себя на компьютере.</p>
+
+<div class="note">
+<p><strong>Замечание</strong>: Вы также можете использовать такие сайты как    <a class="external external-icon" href="http://jsbin.com/">JSBin</a> или <a class="external external-icon" href="https://thimble.mozilla.org/">Thimble</a> для выполнения задания. Вы можте скопировать HTML, CSS и JavaScript в один из этих редакторов. Если онлайн редактор, который вы выбрали, не имеет отдельных панелей для JavaScript/CSS, вы можете выставить код в теги <code>&lt;script&gt;</code>/<code>&lt;style&gt;</code> расположенные на самой HTML странице.</p>
+</div>
+
+<h2 id="Обзор_проекта">Обзор проекта</h2>
+
+<p>В примере вы увидите несколько файлов HTML, CSS и изображений и несколько строк JavaScript кода. Вам нужно написать недостающий JavaScript код для того чтобы галерея заработала. Каркас HTML страницы выглядит так:</p>
+
+<pre class="brush: html">&lt;h1&gt;Пример фотогалереи&lt;/h1&gt;
+
+&lt;div class="full-img"&gt;
+ &lt;img class="displayed-img" src="images/pic1.jpg"&gt;
+ &lt;div class="overlay"&gt;&lt;/div&gt;
+ &lt;button class="dark"&gt;Темнее&lt;/button&gt;
+&lt;/div&gt;
+
+&lt;div class="thumb-bar"&gt;
+
+&lt;/div&gt;</pre>
+
+<p>Результат выглядит следующим образом:</p>
+
+<p><img alt="" src="https://github.com/ConstantineZz/javaScript/blob/master/gallery.png?raw=true" style="height: 639px; width: 827px;"></p>
+
+<ul>
+</ul>
+
+<p>Наиболее интересные части CSS файла из примера:</p>
+
+<ul>
+ <li>Абсолютно позиционированы три элемента внутри <code>&lt;div class="full-img"&gt;</code>:  <code>&lt;img&gt;</code>, в котором отображается полноразмерное изображение, пустой <code>&lt;div class="overlay"&gt;</code>, размер которого имеет тот же размер, что и <code>&lt;img&gt;</code> помещается прямо над предыдущим div-ом (это используется для нанесения эффекта затемнения на изображение через полупрозрачный цвет фона) и <code>&lt;button&gt;</code>, который используется для управления эффектом затемнения.</li>
+ <li>Задана ширина  любых изображений внутри <code>&lt;div class="thumb-bar"&gt;</code> (так называемые «уменьшенные изображения») до 20% и размещены слева так, чтобы они следовали друг за другом на линии.</li>
+</ul>
+
+<p>Ваш JavaScript должен:</p>
+
+<ul>
+ <li>Переберите все изображения, и для каждого вставьте элемент <code>&lt;img&gt;</code> внутри <code>thumb-bar &lt;div&gt;</code>, который будет вставлять это изображение на страницу.</li>
+ <li>Прикрепите обработчик <code>onclick</code> к каждому <code>&lt;img&gt;</code> внутри <code>thumb-bar &lt;div&gt;</code>, чтобы при нажатии на них соответствующее изображение отображалось в элементе <code>display-img &lt;img&gt;</code>.</li>
+ <li>Прикрепите обработчик <code>onclick</code> к кнопке <code>&lt;button&gt;</code>, чтобы при нажатии на нее к полноразмерному изображению был применен эффект затемнения. При повторном нажатии эффект затемнения снова удаляется.</li>
+</ul>
+
+<p>Чтобы лучше понять идею, посмотрите на <a href="https://mdn.github.io/learning-area/javascript/building-blocks/gallery/">готовый пример</a> (не заглядывая в исходный код!).</p>
+
+<h2 id="Этапы_выполнения">Этапы выполнения</h2>
+
+<p>В следующих разделах описывается, что вам нужно делать.</p>
+
+<h3 id="Зацикливание_изображений">Зацикливание изображений</h3>
+
+<p>В файле main.js уже предоставлены строки, в которых хранится ссылка на <code>thumb-bar &lt;div&gt;</code> внутри переменной с именем <code>thumbBar</code>, создают новый элемент <code>&lt;img&gt;</code>, устанавливают его атрибут <code>src</code> на значение placeholder <code>xxx</code> и добавляют этот новый <code>&lt;img&gt;</code> элемент внутри <code>thumbBar</code>.</p>
+
+<p>Нужно сделать:</p>
+
+<ol>
+ <li>Поместите раздел кода под комментарием <code>/* Looping through images */</code> внутри цикла, который перебирает все 5 изображений - вам просто нужно перебрать пять чисел, каждое из которых представляет каждое изображение.</li>
+ <li>В каждой итерации цикла замените значение-заполнитель <code>xxx</code> строкой, которая будет равна пути к изображению в каждом случае. Мы устанавливаем значение атрибута <code>src</code> для этого значения в каждом случае. Имейте в виду, что в каждом случае изображение находится внутри каталога изображений, а его имя - <code>pic1.jpg</code>, <code>pic2.jpg</code> и т.д.</li>
+</ol>
+
+<h3 id="Добавление_обработчика_onclick_к_каждому_уменьшенному_изображению">Добавление обработчика onclick к каждому уменьшенному изображению</h3>
+
+<p>В каждой итерации цикла вам нужно добавить обработчик <code>onclick</code> к текущему <code>newImage</code>:</p>
+
+<ol>
+ <li>Найдите значение атрибута <code>src</code> текущего изображения. Это можно сделать, запустив функцию <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute">getAttribute()</a></code> в <code>&lt;img&gt;</code> в каждом случае и передав ей параметр <code>«src»</code> в каждом случае. Но как получить изображение? Использование <code>newImage</code> не будет работать, так как цикл завершается до применения обработчиков событий; это приведет к тому, что значение <code>src</code> последнего <code>&lt;img&gt;</code> будет возвращено в каждом случае. Чтобы решить это, имейте в виду, что в случае каждого обработчика события <code>&lt;img&gt;</code> является целью обработчика. Как получить информацию от объекта события?</li>
+ <li>Запустите функцию, передав ей возвращаемое значение <code>src</code> в качестве параметра. Вы можете вызвать эту функцию, как хотите.</li>
+ <li>Эта функция обработчика событий должна установить значение атрибута <code>src</code> <code>displayed-img &lt;img&gt;</code> равным значению <code>src</code>, переданному в качестве параметра. Мы уже предоставили вам строку, в которой хранится ссылка на соответствующий <code>&lt;img&gt;</code> в переменной с именем <code>displayedImg</code>. Обратите внимание, что здесь нам нужна определенная именованная функция.</li>
+</ol>
+
+<h3 id="Написание_обработчика_который_запускает_кнопку_затемнения_подсветки">Написание обработчика, который запускает кнопку затемнения / подсветки</h3>
+
+<p>Мы уже предоставили строку, в которой хранится ссылка на <code>&lt;button&gt;</code> в переменной <code>btn</code>. Вам нужно добавить обработчик <code>onclick</code>, который:</p>
+
+<ol>
+ <li>Проверяет текущее имя класса, установленное на кнопке <code>&lt;button&gt;</code> — для этого снова можно использовать <code>getAttribute()</code>.</li>
+ <li>Если имя класса <code>"dark"</code>, изменяет класс <code>&lt;button&gt;</code> на <code>"light"</code> (с помощью <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute">setAttribute()</a></code>), его текстовое содержимое на "Светлее" и {{cssxref("background-color")}} наложения <code>&lt;div&gt;</code> на <code>"rgba (0,0,0,0.5)"</code>.</li>
+ <li>Если имя класса не «темное», изменяет класс <code>&lt;button&gt;</code> на <code>"dark"</code>, его текстовое содержимое обратно на "Темнее" и {{cssxref("background-color")}} наложения <code>&lt;div&gt;</code> на <code>"rgba(0,0,0,0)"</code>.</li>
+</ol>
+
+<p>Следующие строки служат основой для достижения изменений, указанных в пунктах 2 и 3 выше.</p>
+
+<pre class="brush: js">btn.setAttribute('class', xxx);
+btn.textContent = xxx;
+overlay.style.backgroundColor = xxx;</pre>
+
+<h2 id="Советы_и_подсказки">Советы и подсказки</h2>
+
+<ul>
+ <li>Вам не нужно каким-либо образом редактировать HTML или CSS.</li>
+</ul>
+
+<h2 id="Оценка">Оценка</h2>
+
+<p>Если вы проводите эту оценку в рамках организованного курса, вы должны уметь отдать свою работу своему учителю/наставнику для маркировки. Если вы самообучаетесь, то вы можете получить руководство по маркировке довольно легко, задав тему <a href="https://discourse.mozilla.org/t/image-gallery-assessment/24687">обсуждения об этом упражнении</a> или в IRC-канале <a href="irc://irc.mozilla.org/mdn">#mdn</a> в <a href="https://wiki.mozilla.org/IRC">Mozilla IRC</a>. Сначала попробуйте упражнение - ничего не выиграть от обмана!</p>
+
+<p>{{PreviousMenu("Learn/JavaScript/Building_blocks/Events", "Learn/JavaScript/Building_blocks")}}</p>
+
+<p> </p>
+
+<h2 id="В_этом_модуле">В этом модуле</h2>
+
+<ul>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/Building_blocks/conditionals">Принятие решений в Вашем коде — условные конструкции</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/Building_blocks/Looping_code">Зацикливание кода</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/Building_blocks/Functions">Функции — Переиспользуемые блоки кода</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">Создайте свою собственную функцию</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/Building_blocks/Return_values">Возвращаемое значение функции</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/Building_blocks/%D0%A1%D0%BE%D0%B1%D1%8B%D1%82%D0%B8%D1%8F">Введение в события</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/Building_blocks/Image_gallery">Создание галереи</a></li>
+</ul>
diff --git a/files/ru/learn/javascript/building_blocks/index.html b/files/ru/learn/javascript/building_blocks/index.html
new file mode 100644
index 0000000000..16b54aff16
--- /dev/null
+++ b/files/ru/learn/javascript/building_blocks/index.html
@@ -0,0 +1,61 @@
+---
+title: Структурные элементы JavaScript
+slug: Learn/JavaScript/Building_blocks
+tags:
+ - JavaScript
+ - Введение
+ - Гид
+ - Знакомство
+ - Модуль
+ - Написание кода
+ - НаписаниеКода
+ - Начинающий
+ - Новичок
+ - Оценивание
+ - Раздел
+ - Руководство
+ - Статья
+ - Условия
+ - Функции
+ - лендинг
+ - события
+ - циклы
+translation_of: Learn/JavaScript/Building_blocks
+---
+<div>{{LearnSidebar}}</div>
+
+<p class="summary">В данном разделе мы продолжим знакомство с ключевыми основами JavaScript, обратим внимание на часто используемые приёмы программирования, такие как условные выражения, циклы, функции и события. Все они уже встречались Вам ранее в данном курсе, но только поверхностно, далее они будут рассмотрены подробнее.</p>
+
+<h2 id="Предварительное_условие">Предварительное условие</h2>
+
+<p>До начала изучения следующего раздела Вам нужно тщательно ознакомиться с основами <a href="/en-US/docs/Learn/HTML/Introduction_to_HTML">HTML</a> и <a href="/en-US/docs/Learn/CSS/Introduction_to_CSS">CSS</a>, так же обязательно прочтите курс "<a href="/ru/docs/Learn/JavaScript/%D0%9F%D0%B5%D1%80%D0%B2%D1%8B%D0%B5_%D1%88%D0%B0%D0%B3%D0%B8">Первые шаги в JavaScript</a>".</p>
+
+<div class="note">
+<p><span style="font-size: 14px;"><strong>Примечание</strong></span>: если устройство на котором Вы изучаете данный курс не позволяет создавать/сохранять файлы, в большинстве случаев примеры кода могут быть запущены в таких онлайн приложениях как <a href="http://jsbin.com/">JSBin</a> или <a href="https://thimble.mozilla.org/">Thimble</a>.</p>
+</div>
+
+<h2 id="Руководства">Руководства</h2>
+
+<dl>
+ <dt><a href="/ru/docs/Learn/JavaScript/Building_blocks/conditionals">Принятие решений в Вашем коде — условные конструкции</a></dt>
+ <dd>В любом языке программирования необходимо принимать решения и совершать действия в зависимости от полученных в процессе исполнения программы или введённых пользователем данных. Например, игра должна завершиться, когда число жизней персонажа игрока достигает нуля. В приложении для прогноза погоды отображается картинка с восходящим солнцем, если смотреть утром, со звёздами и луной — ночью. В данной статье исследуется работа условных конструкций в JavaScript.</dd>
+ <dt><a href="/ru/docs/Learn/JavaScript/Building_blocks/Looping_code">Зацикливание кода</a></dt>
+ <dd>Иногда требуется, чтобы действие исполнялось несколько раз подряд. Например, при просмотре списка имён. В программировании для данной цели успешно применяются циклы.  Здесь мы познакомимся с использованием циклов в JavaScript.</dd>
+ <dt><a href="/ru/docs/Learn/JavaScript/Building_blocks/Functions">Функции — блоки кода используемые многократно</a></dt>
+ <dd>Другая необходимая концепция в программировании это <strong>функции</strong>. <strong>Функции</strong> позволяют сохранить часть кода для решения определённой задачи в определённом блоке, и затем вызывать этот код, тогда, когда это тебе необходимо при помощи короткой команды — это намного лучше, чем писать один и тот же код несколько раз. В статье будут рассмотрена фундаментальная концепция функции: основной синтаксис, как вызывать и как определять функции,  области видимости и параметры.</dd>
+ <dt><a href="/ru/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">Создай свою функцию</a></dt>
+ <dd>В отличие от большинства предыдущих статей,  рассматривающих только теорию, эта статья даёт практический опыт. Здесь вы получите практику создания собственных функций. На ряду с возможностями, мы также объясним дополнительные полезные подробности, связанные с функциями.</dd>
+ <dt><a href="/ru/docs/Learn/JavaScript/Building_blocks/Return_values">Функции возвращают значения</a></dt>
+ <dd>Есть одно из существенных понятий для нас, представленное в этом курсе, которое достойно пристального внимания — возврат значений функции. Некоторые функции не возвращают значений после завершения,  но другие делают это. Главное понять, что это за значения, как использовать их в Вашем коде, и как заставить Вашу собственную функцию возвратить необходимые значения. </dd>
+ <dt><a href="/ru/docs/Learn/JavaScript/Building_blocks/События">Введение в события</a></dt>
+ <dd>События — это действия или явления, которые происходят в системе во время программирования, о которых система сообщает, и, при желании, на которые можно ответить. Например, когда пользователь кликает на кнопку на странице, возможно Вы захотите вывести на экран блок с информацией, как ответ на это событие. В последней статье мы обсудим важные концепции, связанные с событиями, и увидим, как они работают в браузерах.</dd>
+</dl>
+
+<h2 id="Проверка_знаний">Проверка знаний</h2>
+
+<p>Следующая оценка проверит Ваше понимание основ JavaScript, описанных в данном руководстве.</p>
+
+<dl>
+ <dt><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Image_gallery">Фотогалерея</a></dt>
+ <dd>Теперь, когда мы рассмотрели основные блоки JavaScript, мы проверим твои знания о циклах, функциях, регулярных выражениях и событиях, создав довольно общий элемент, который вы увидите на многих сайтах - галерея изображений, работающей с помощью JavaScript.</dd>
+</dl>
diff --git a/files/ru/learn/javascript/building_blocks/looping_code/index.html b/files/ru/learn/javascript/building_blocks/looping_code/index.html
new file mode 100644
index 0000000000..68f82b6d7b
--- /dev/null
+++ b/files/ru/learn/javascript/building_blocks/looping_code/index.html
@@ -0,0 +1,936 @@
+---
+title: Зацикливание кода
+slug: Learn/JavaScript/Building_blocks/Looping_code
+translation_of: Learn/JavaScript/Building_blocks/Looping_code
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/conditionals","Learn/JavaScript/Building_blocks/Functions", "Learn/JavaScript/Building_blocks")}}</div>
+
+<p class="summary">Языки программирования очень полезны для быстрой реализации повторяющихся задач. От базовых числовых операций до любой другой ситуации, когда у вас есть много похожих операций, которые нужно выполнить. В этой статье мы рассмотрим структуры циклов, доступные в JavaScript, которые можно использовать для этих целей.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Требования:</th>
+ <td>Базовые значения компьютерной системы и базовое понимаение HTML и CSS, <a href="/en-US/docs/Learn/JavaScript/First_steps">JavaScript первые шаги</a>.</td>
+ </tr>
+ <tr>
+ <th scope="row">Цель:</th>
+ <td>Понять как работают циклы в JavaScript.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Циклы_в_коде">Циклы в коде</h2>
+
+<p>Циклы являются важной концепцией в программировании. Их использование основано на повторении одного и того же, что в программировании называется <strong>итерацией</strong>.</p>
+
+<p>Давайте рассмотрим работу фермера, который следит за тем, чтобы у него было достаточно еды, чтобы кормить всю свою семью в течении недели. Его работу можно представить в виде цикла:</p>
+
+<p><br>
+ <img alt="" src="https://mdn.mozillademos.org/files/13755/loop_js-02-farm.png" style="display: block; margin: 0 auto;"></p>
+
+<p>Цикл обычно составляет одну или несколько из следующих функций:</p>
+
+<ul>
+ <li> <strong>Счетчик</strong>, который инициализируется с определенного значения — начальной точки цикла (На рисунке выше первый этап: "у меня нет еды (i have no food)")</li>
+ <li><strong>Условие выхода </strong>— критерией, при котором цикл останавливается, — обычно наступает, когда цикл достигает определенного значения. Это иллюстрируется выше словами "Достаточно ли у меня еды? (Do I have enough food?)". Предположим, фермеру нужно 10 порций еды, чтобы прокормить семью.</li>
+ <li><strong>Итератор </strong>постепенно увеличивает счетчик на некоторое значение на каждом шаге цикла, пока не достигнуто условия выхода. Мы явно не показали это в изображении, но если предположить что фермер собирает две порции еды в час, то после каждого часа, количество еды, которое у него имеется, увеличивается на две порции, и он проверяет достаточно ли у него еды сейчас. Если у него собралось 10 порций (условие выхода), он может остановить сбор и вернуться домой.</li>
+</ul>
+
+<p>В <a href="/ru/docs/Словарь/Pseudocode">псевдокоде</a> это будет выглядеть следующим образом:</p>
+
+<pre class="notranslate">loop(food = 0; foodNeeded = 10) {
+ if (food = foodNeeded) {
+ exit loop;
+ // У нас достаточно еды, пора домой
+ } else {
+ food += 2; // Прошел час, количество еды увеличилось на 2
+ // переход на следующую итерацию цикла.
+ }
+}</pre>
+
+<p>Таким образом, необходимое количество еды устанавливается равным 10, а изначально фермер не имеет ни одной порции, т.е. начало равно 0. На каждой итерации цикла проверяем, соответствует ли собранное количество еды, с тем количеством, которое ему необходимо. Если это так, можно выйти из цикла, если нет, фермер собирает еще 2 порции и снова переходит к проверке.</p>
+
+<h3 id="Зачем_это_нужно">Зачем это нужно?</h3>
+
+<p>Итак вы разобрались, как работают циклы. Но, вероятно, думаете: "Хорошо, но как это мне поможет писать код на JavaScript". Как мы писали ранее, <strong>циклы постоянно повторяют одно и тоже действие</strong>, что отлично подходит для <strong>быстрого выполнения повторяющихся задач</strong>.</p>
+
+<p>Часто код будет немного отличаться на каждой последующей итерации цикла. Это означает, что вы можете выполнять задачи, которые похожи, но у них есть некоторые различия. Например, если вам нужно выполнить много вычислений, немного отличающихся на каждой итерации.</p>
+
+<p>На следующем примере попробуем показать, почему циклы так полезны. Предположим мы хотели нарисовать 100 случайных кругов на элементе {{htmlelement("canvas")}}. Нажмите кнопку "Обновить", чтобы снова и снова запускать пример и увидеть, что круги рисуются случайным образом.</p>
+
+<div class="hidden">
+<h6 id="Hidden_code">Hidden code</h6>
+
+<pre class="brush: html notranslate">&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+ &lt;head&gt;
+ &lt;meta charset="utf-8"&gt;
+ &lt;title&gt;Random canvas circles&lt;/title&gt;
+ &lt;style&gt;
+ html {
+ width: 100%;
+ height: inherit;
+ background: #ddd;
+ }
+
+ canvas {
+ display: block;
+ }
+
+ body {
+ margin: 0;
+ }
+
+ button {
+ position: absolute;
+ top: 5px;
+ left: 5px;
+ }
+ &lt;/style&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+
+ &lt;button&gt;Обновить&lt;/button&gt;
+
+ &lt;canvas&gt;&lt;/canvas&gt;
+
+
+ &lt;script&gt;
+ var btn = document.querySelector('button');
+ var canvas = document.querySelector('canvas');
+ var ctx = canvas.getContext('2d');
+
+ var WIDTH = document.documentElement.clientWidth;
+ var HEIGHT = document.documentElement.clientHeight;
+
+ canvas.width = WIDTH;
+ canvas.height = HEIGHT;
+
+ function random(number) {
+ return Math.floor(Math.random()*number);
+ }
+
+ function draw() {
+ ctx.clearRect(0,0,WIDTH,HEIGHT);
+ for (var i = 0; i &lt; 100; i++) {
+ ctx.beginPath();
+ ctx.fillStyle = 'rgba(255,0,0,0.5)';
+ ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI);
+ ctx.fill();
+ }
+ }
+
+ btn.addEventListener('click',draw);
+
+ &lt;/script&gt;
+
+ &lt;/body&gt;
+&lt;/html&gt;</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Hidden_code', '100%', 400) }}</p>
+
+<p>Вам необязательно понимать все части кода, но давайте посмотрим на место, где рисуются 100 кругов.</p>
+
+<pre class="brush: js notranslate">for (var i = 0; i &lt; 100; i++) {
+ ctx.beginPath();
+ ctx.fillStyle = 'rgba(255,0,0,0.5)';
+ ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI);
+ ctx.fill();
+}</pre>
+
+<ul>
+ <li><code>random()</code>, описанная в коде, возвращает случайное число между <code>0</code> и <code>x-1</code>.</li>
+ <li><code>WIDTH</code> и <code>HEIGHT</code> — это высота и ширина  окна браузера.</li>
+</ul>
+
+<p>Вы должны понять основную идею: мы используем цикл для запуска 100 итераций этого кода, каждая из которых рисует круг в случайном месте в окне. Количество кода было бы одинаковым, если бы нам нужно было нарисовать 10, 100 или 1000 кругов, поменяется лишь одно число.</p>
+
+<p>Если бы мы не использовали циклы, нам бы пришлось повторить следующий код, для отрисовки каждого круга:</p>
+
+<pre class="brush: js notranslate">ctx.beginPath();
+ctx.fillStyle = 'rgba(255,0,0,0.5)';
+ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI);
+ctx.fill();</pre>
+
+<p>Это множество лишнего кода очень усложнило бы подержку кода в будущем, т.к. если бы вам захотелось что-то изменить, в каждой итерации цикла, пришлось бы изменять все части кода по отдельности. А ещё это усложнаяет поиск ошибок, т.к. если вдруг вы совершите логическую ошибку при описании одной из итераций, придется потратить много времени на ее поиски.</p>
+
+<h2 id="Правила_записи_цикла">Правила записи цикла</h2>
+
+<p>Рассмотрим некоторые конкретные конструкции циклов. Первый вариант, который вы будете использовать чаще всего, это цикл <a href="/ru/docs/Web/JavaScript/Reference/Statements/for">for</a>. Он имеет следующий синтаксис:</p>
+
+<pre class="notranslate">for (initializer; exit-condition; final-expression) {
+ // код для выполнения
+}</pre>
+
+<p>Тут имеем:</p>
+
+<ol>
+ <li>Ключевое слово <a href="ru/docs/Web/JavaScript/Reference/Statements/for">for</a>, за которым следуют круглые скобки.</li>
+ <li>В круглых скобках у нас есть три части, разделенные точой с запятой:
+ <ol>
+ <li><strong>Инициализатор</strong> — обычно это переменная численного типа, которая увеличивается каждую итерацию, чтобы посчитать количество шагов цикла. Ее также называет <strong>счетчиком</strong>.</li>
+ <li><strong>Условие выхода</strong> — как упоминалось ранее, определяет, когда цикл должен остановиться. Обычно это выражение с оператором сравнения проверяющим, выполнено ли условие выхода.</li>
+ <li><strong>Окончательное выражение</strong> — вычисляется (или выполняется) каждый раз, когда цикл проходит полную итерацию. Обычно оно служит для увеличения (или уменьшения) переменной <strong>счетчика</strong>, чтобы приблизить ее значение к условию выхода.</li>
+ </ol>
+ </li>
+ <li>Фигурные скобки, содержащие блок кода. Этот код будет запускаться на каждой итерации цикла.</li>
+</ol>
+
+<p>Посмотрим на пример, чтобы разобраться в этом более детально.</p>
+
+<pre class="brush: js notranslate">var cats = ['Билл', 'Макс', 'Пикси', 'Алиса', 'Жасмин'];
+var info = 'Моих кошек зовут ';
+var para = document.querySelector('p');
+
+for (var i = 0; i &lt; cats.length; i++) {
+ info += cats[i] + ', ';
+}
+
+para.textContent = info;</pre>
+
+<p>Этот блок кода будет иметь следующий результат:</p>
+
+<div class="hidden">
+<h6 id="Hidden_code_2">Hidden code 2</h6>
+
+<pre class="brush: html notranslate">&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+ &lt;head&gt;
+ &lt;meta charset="utf-8"&gt;
+ &lt;title&gt;Пример цикла For&lt;/title&gt;
+ &lt;style&gt;
+
+ &lt;/style&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+
+ &lt;p&gt;&lt;/p&gt;
+
+
+ &lt;script&gt;
+ var cats = ['Билл', 'Макс', 'Пикси', 'Алиса', 'Жасмин'];
+ var info = 'Моих кошек зовут: ';
+ var para = document.querySelector('p');
+
+ for (var i = 0; i &lt; cats.length; i++) {
+ info += cats[i] + ', ';
+ }
+
+ para.textContent = info;
+
+ &lt;/script&gt;
+
+ &lt;/body&gt;
+&lt;/html&gt;</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Hidden_code_2', '100%', 60) }}</p>
+
+<div class="note">
+<p><strong>Заметка</strong>: Вы можете найти этот  <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/basic-for.html">пример на GitHub</a> или  <a href="http://mdn.github.io/learning-area/javascript/building-blocks/loops/basic-for.html">посмотреть онлайн</a>.</p>
+</div>
+
+<p>Здесь показан цикл, используемый для перебора элементов в массиве и выполнения определенных действий с каждым из них — очень распространенный шаблон в JavaScript<br>
+ Подробнее:</p>
+
+<ol>
+ <li>Итератор, <code>i</code>, начинается с <code>0</code> (<code>var i = 0</code>).</li>
+ <li>Цикл запускается, пока значение итератора не будет больше длины массива кошек. Это важно - условие выхода показывает когда именно цикл должен работать, а когда нужно выйти из цикла. Поэтому в случае, пока <code>i &lt; cats.lenght</code> по-прежнему возвращает <code>true</code>, цикл будет работать.</li>
+ <li>Внутри тела цикла мы соединяем текущий элемент цикла (<code>cats[i]</code> это <code>cats</code>[независимо от того, чем <code>i</code> является в данный момент]) с запятой и пробелом. Итак:
+ <ol>
+ <li>В начале, <code>i = 0</code>, поэтому <code>cats[0] + ', '</code> соеденятся в ("Билл, ").</li>
+ <li>На втором шаге, <code>i = 1</code>, поэтому <code>cats[1] + ', '</code> соединятся в ("Макс, ")</li>
+ <li>И так далее. В конце каждого цикла <code>i</code> увеличится на 1 (<font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">i++</span></font>) , и процесс будет начинаться заново.</li>
+ </ol>
+ </li>
+ <li>Когда <code>i</code> достигнет величины <code>cats.length</code> цикл остановится и браузер перейдет к следующему фрагменту кода после цикла.</li>
+</ol>
+
+<div class="note">
+<p><strong>Заметка</strong>: Мы добавили условия выхода <code>i &lt; cats.length</code>, а не <code>i &lt;= cats.length</code>, потому что компьютеры считают с  0,  а не с 1 — в начале <code>i = 0</code> и увеличивается до <code>i = 4</code> (индекс последнего элемента массива). <code>cats.length</code> возвращает 5, т.к. в массиве 5 элементов, но нам не нужно увеличивать до <code>i = 5</code>, т.к. <code>cats[5] </code>вернет <code>undefined</code> (в массиве нет элемента с индексом 5). Таким образом мы хотим придти к результату на 1 меньше, поэтому <code>i &lt; cats.length</code>, не одно и тоже что <code>i &lt;= cats.length</code>.</p>
+</div>
+
+<div class="note">
+<p><strong>Заметка</strong>: Стандартной ошибкой с условием выхода является использование условия "равный" (<code>===</code>) ,а не "меньше или равно" (<code>&lt;=</code>). Если нам нужно увеличить счетчик до <code>i = 5</code>, условие выхода должно быть <code>i &lt;= cats.length</code>. Если мы установим <code>i === cats.length</code>, цикл не начнется, т.к. <code>i</code> не равно <code>5</code> на самой первой итерации, поэтому цикл остановится сразу.</p>
+</div>
+
+<p>Остается одна небольшая проблема: выходная строка сформирована не совсем корректно:</p>
+
+<blockquote>
+<p>Моих кошек зовут  Билл, Макс, Пикси, Алиса, Жасмин,</p>
+</blockquote>
+
+<p>В идеале мы хотим изменить конкатенацию на последней итерации цикла так, чтобы у нас не было запятой в конце предложения. Для этого нужно добавить условное выражение внутрь цикла <code>for</code> для обработки этого особого случая:</p>
+
+<pre class="brush: js notranslate">for (var i = 0; i &lt; cats.length; i++) {
+ if (i === cats.length - 1) {
+ info += 'и ' + cats[i] + '.';
+ } else {
+ info += cats[i] + ', ';
+ }
+}</pre>
+
+<div class="note">
+<p><strong>Заметка</strong>: Вы можете найти этот <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/basic-for-improved.html">пример на GitHub</a> или <a href="http://mdn.github.io/learning-area/javascript/building-blocks/loops/basic-for-improved.html">посмотреть онлайн</a>.</p>
+</div>
+
+<div class="warning">
+<p><strong>Важно</strong>: С цкилом <strong>for</strong>, также как и сдругими циклами, вы должны убедиться что инициализатор (счетчик) и окончательное выражение построены так, что они достигнут условия выхода. Если этого не произойдет, то цикл будет продолжаться вечно. В итоге браузер или заставит его остановиться, или выдаст ошибку. Это называется <strong>бесконечным циклом</strong>.</p>
+</div>
+
+<h2 id="Выход_из_цикла_с_помощью_break">Выход из цикла с помощью break</h2>
+
+<p>Если вы хотите выйти из цикла до завершения всех итераций, вы можете использовать оператор <a href="/ru/docs/Web/JavaScript/Reference/Statements/break">break</a> . Мы уже встречались с ним в предыдущей статье, когда рассматривали оператор <a href="/ru/docs/Learn/JavaScript/Building_blocks/conditionals#Оператор_switch">switch</a>: когда происходит событие, соответствующее условию, прописанному ключевым словом <code>case</code> внутри оператора <code>switch</code>, условие break моментально выходит из конструкции <code>switch</code> и запускает следующий после нее код.</p>
+
+<p>Тоже самое и с циклами — условие <code>break</code> моментально закончит цикл и заставит браузер запустить следующий после цикла код.</p>
+
+<p>Предположим, в массиве данных мы хотим найти имена контактов и телефонные номера, а вернуть только номер, который мы нашли.<br>
+ Начнем с разметки HTML: поле {{htmlelement("input")}} позволяет нам ввести имя для поиска, элемент (кнопка) {{htmlelement("button")}} для подтверждения поиска, и элемент {{htmlelement("p")}} для отображения результата:</p>
+
+<pre class="brush: html notranslate">&lt;label for="search"&gt;Поиск по имени: &lt;/label&gt;
+&lt;input id="search" type="text"&gt;
+&lt;button&gt;Поиск&lt;/button&gt;
+
+&lt;p&gt;&lt;/p&gt;</pre>
+
+<p>Теперь в JavaScript:</p>
+
+<pre class="brush: js notranslate">var contacts = ['Григорий:2232322', 'Марина:3453456', 'Василий:7654322', 'Наталья:9998769', 'Диана:9384975'];
+var para = document.querySelector('p');
+var input = document.querySelector('input');
+var btn = document.querySelector('button');
+
+btn.addEventListener('click', function() {
+ var searchName = input.value;
+ input.value = '';
+ input.focus();
+ for (var i = 0; i &lt; contacts.length; i++) {
+ var splitContact = contacts[i].split(':');
+ if (splitContact[0] === searchName) {
+ para.textContent = splitContact[0] + ', тел.: ' + splitContact[1] + '.';
+ break;
+ } else {
+ para.textContent = 'Контакт не найден.';
+ }
+ }
+});</pre>
+
+<div class="hidden">
+<h6 id="Hidden_code_3">Hidden code 3</h6>
+
+<pre class="brush: html notranslate">&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+ &lt;head&gt;
+ &lt;meta charset="utf-8"&gt;
+ &lt;title&gt;Simple contact search example&lt;/title&gt;
+ &lt;style&gt;
+
+ &lt;/style&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+
+ &lt;label for="search"&gt;Найти имя контакта: &lt;/label&gt;
+ &lt;input id="search" type="text"&gt;
+ &lt;button&gt;Поиск&lt;/button&gt;
+
+ &lt;p&gt;&lt;/p&gt;
+
+
+ &lt;script&gt;
+ var contacts = ['Григорий:2232322', 'Марина:3453456', 'Василий:7654322', 'Наталья:9998769', 'Диана:9384975'];
+ var para = document.querySelector('p');
+ var input = document.querySelector('input');
+ var btn = document.querySelector('button');
+
+ btn.addEventListener('click', function() {
+ var searchName = input.value;
+ input.value = '';
+ input.focus();
+ for (var i = 0; i &lt; contacts.length; i++) {
+ var splitContact = contacts[i].split(':');
+ if (splitContact[0] === searchName) {
+ para.textContent = splitContact[0] + ', тел.: ' + splitContact[1] + '.';
+ break;
+ } else if (i === contacts.length-1)
+  para.textContent = 'Контакт не найден.';
+  }
+ });
+ &lt;/script&gt;
+
+ &lt;/body&gt;
+&lt;/html&gt;</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Hidden_code_3', '100%', 100) }}</p>
+
+<ol>
+ <li>Прежде всего у нас определены некоторые переменные: у нас есть массив с контактной информацией, каждый элемент которого это строка, содержащая в себе имя и номер телефона, которые разделенны двоеточием.</li>
+ <li>Далее мы применяем обработчик события для кнопки (<code>btn</code>), чтобы при её нажатии запускался код для поиска и отображения результатов.</li>
+ <li>Мы сохраняем значение, введенное в текстовое поле, в переменную  <code>searchName</code>, затем очищаем введеный текст и снова фокусируемся на текстовом поле для нового поиска.</li>
+ <li>Теперь перейдем к интересующей нас части — к циклу <code>for</code>:
+ <ol>
+ <li>Мы начали счетчик с <code>0</code>, запускаем цикл до тех пор, пока счетчик всё ещё меньше, чем contacts.length, а инкремент <code>i</code> увеличиваем на 1 после каждой иттерации цикла.</li>
+ <li>Внутри цикла мы сначала разделяем текущий контакт (<code>contacts[i]</code>) на символе двоеточия, и сохраняем полученные два значения в массиве с  названием <code>splitContact</code>.</li>
+ <li>Затем мы используем условный оператор, чтобы проверить, равно ли <code>splitContact[0]</code> (имя контакта) введеному <code>searchName</code>. Если это так, мы выводим строку в абзац, чтобы сообщить, каков номер контакта, и используем <code>break</code> для завершения цикла.</li>
+ </ol>
+ </li>
+ <li>
+ <p>После <a href="https://ru.wikipedia.org/wiki/%D0%98%D1%82%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F_(%D0%B7%D0%BD%D0%B0%D1%87%D0%B5%D0%BD%D0%B8%D1%8F)">итерации</a> <code>(contacts.length-1)</code>, если имя контакта не совпадает с введенным именем в поисковом запросе, для текста абзаца устанавливается: «Контакт не найден.», и цикл продолжает повторяться.</p>
+ </li>
+</ol>
+
+<div class="note">
+<p>Заметка: Вы можете посмотреть исходный код на <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/contact-search.html">GitHub</a>  или запустить его (also <a href="http://mdn.github.io/learning-area/javascript/building-blocks/loops/contact-search.html">see it running live</a>).</p>
+</div>
+
+<h2 id="Пропуск_итераций_с_продолжением">Пропуск итераций с продолжением</h2>
+
+<p>Оператор <a href="/ru/docs/Web/JavaScript/Reference/Statements/continue">continue</a> работает аналогичным образом, как и <code>break</code>, но вместо полного выхода из цикла он переходит к следующей итерации цикла.</p>
+
+<p>Рассмотрим другой пример, в котором в качестве вводных данных принимается число, а возвращаются только числа, которые являются квадратами целых чисел.</p>
+
+<p>Код HTML в основном такой же, как и в предыдущем примере — простой ввод текста и абзац для вывода.  JavaScript в основном такой же, хотя сам цикл немного другой:</p>
+
+<pre class="brush: js notranslate">var num = input.value;
+
+for (var i = 1; i &lt;= num; i++) {
+ var sqRoot = Math.sqrt(i);
+ if (Math.floor(sqRoot) !== sqRoot) {
+ continue;
+ }
+
+ para.textContent += i + ' ';
+}</pre>
+
+<p>Вывод:</p>
+
+<div class="hidden">
+<h6 id="Hidden_code_4">Hidden code 4</h6>
+
+<pre class="brush: html notranslate">&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+ &lt;head&gt;
+ &lt;meta charset="utf-8"&gt;
+ &lt;title&gt;Генератор целочисленных квадратов&lt;/title&gt;
+ &lt;style&gt;
+
+ &lt;/style&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+
+ &lt;label for="number"&gt;Введите число: &lt;/label&gt;
+ &lt;input id="number" type="text"&gt;
+ &lt;button&gt;Генерация целочисленных квадратов&lt;/button&gt;
+
+ &lt;p&gt;Результат: &lt;/p&gt;
+
+
+ &lt;script&gt;
+ var para = document.querySelector('p');
+ var input = document.querySelector('input');
+ var btn = document.querySelector('button');
+
+ btn.addEventListener('click', function() {
+ var num = input.value;
+ input.value = '';
+ input.focus();
+ para.textContent = 'Вы ввели: ' + num + '. Результат: ';
+ for (var i = 1; i &lt;= num; i++) {
+ var sqRoot = Math.sqrt(i);
+ if (Math.floor(sqRoot) !== sqRoot) {
+ continue;
+ }
+
+ para.textContent += i + ' ';
+ }
+ });
+ &lt;/script&gt;
+
+ &lt;/body&gt;
+&lt;/html&gt;</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Hidden_code_4', '100%', 100) }}</p>
+
+<ol>
+ <li>В этом случае на входе должно быть число (<code>num</code>). Циклу <code>for</code> присваивается счетчик, начинающийся с 1 (поскольку в данном случае нас не интересует 0), условие выхода, которое говорит, что цикл остановится, когда счетчик станет больше входного <code>num</code>, а итератор добавляет 1 к счетчику каждый раз.</li>
+ <li>Внутри цикла мы находим квадратный корень каждого числа с помощью <a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/Math/sqrt">Math.sqrt(i)</a>, а затем проверяем, является ли квадратный корень целым числом, проверяя, совпадает ли он с самим собой, когда он был округлен до ближайшего целого числа (это то, что <code>Math.floor ()</code> делает с числом, которое передает).</li>
+ <li>Если квадратный корень и округленный вниз квадратный корень не равны друг другу <code>(! ==)</code>, значит квадратный корень не является целым числом, поэтому нас он не интересует.  В таком случае мы используем оператор <code>continue</code>, чтобы перейти к следующей итерации цикла без записи этого числа.</li>
+ <li>Если квадратный корень <em>является целым числом</em>, мы пропускаем блок <code>if</code> полностью, поэтому оператор <code>continue</code> не выполняется; вместо этого объединяется текущее значение <code>i</code> с пробелом в конце содержимого абзаца.</li>
+</ol>
+
+<div class="note">
+<p><strong>Примечание. </strong>Вы также можете просмотреть полный исходный код на<strong> </strong><a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/integer-squares.html"> GitHub</a> (так же смотри <a href="https://mdn.github.io/learning-area/javascript/building-blocks/loops/integer-squares.html">этот код вживую</a>).</p>
+</div>
+
+<h2 id="Циклы_while_и_do...while">Циклы <code>while</code> и <code>do...while</code></h2>
+
+<p><code><strong>for</strong> </code>— <code>не единственный тип цикла, доступный в JavaScript.</code> На самом деле существует множество других типов циклов. И хотя сейчас не обязательно знать их все, стоит взглянуть на структуру нескольких других, чтобы вы могли распознать те же функции, но в работе немного по-другому.</p>
+
+<p>Рассмотрим цикл <a href="/ru/docs/Web/JavaScript/Reference/Statements/while">while</a>. Синтаксис этого цикла выглядит так:</p>
+
+<pre class="notranslate">initializer
+while (exit-condition) {
+ // code to run
+
+ final-expression
+}</pre>
+
+<p>Его действие очень похоже на цикл <code>for</code>, но переменная инициализатора устанавливается перед циклом, а заключительное выражение включается в цикл после запуска кода. Напомним, у цикла <code>for</code> эти два элемента заключены в круглых скобках. Здесь же после ключевого слова <code>while в круглых скобках заключено условие выхода из цикла.</code></p>
+
+<p>Здесь присутствуют те же три элемента и в том же порядке, что и в цикле <code>for</code>. Это важно, так как вам нужно определить инициализатор, прежде чем получится проверить, достиг ли цикл условия выхода.</p>
+
+<p>Окончательное условие выполняется после выполнения кода внутри цикла (итерация завершена), и оно выполняется только в том случае, если условие выхода еще не достигнуто.</p>
+
+<p>Посмотрим еще раз пример со списком кошек с кодом переписанным под использование цикла <code>while:</code></p>
+
+<pre class="brush: js notranslate">var i = 0;
+
+while (i &lt; cats.length) {
+ if (i === cats.length - 1) {
+ info += 'and ' + cats[i] + '.';
+ } else {
+ info += cats[i] + ', ';
+ }
+
+ i++;
+}</pre>
+
+<div class="note">
+<p><strong>Примечание: </strong>цикл все еще работает так же, как и ожидалось - посмотрите, <a href="http://mdn.github.io/learning-area/javascript/building-blocks/loops/while.html">как он работает на GitHub</a> (также посмотрите <a href="https://github.com/ConstantineZz/javaScript/blob/master/while.html">полный исходный код</a>).</p>
+</div>
+
+<p>Цикл<strong> <a href="/ru/docs/Web/JavaScript/Reference/Statements/do...while">do...while</a></strong> представляет собой вариацию структуры цикла <code>while</code>:</p>
+
+<pre class="notranslate">initializer
+do {
+ // code to run
+
+ final-expression
+} while (exit-condition)</pre>
+
+<p>В этом случае инициализатор снова указывается прежде, чем цикл запускается. Ключевое слово <code>do</code> непосредственно предшествует фигурным скобкам, содержащим код для запуска и конечное выражение.</p>
+
+<p>Различие состоит в том, что условие выхода идет после всего остального, заключенное в скобки после ключевого слова <code>while</code>. В цикле <code>do...while</code> код внутри фигурных скобок всегда запускается один раз, прежде чем выполняется проверка, чтобы увидеть, должна ли она быть выполнена снова (в <code>while</code> и <code>for</code> проверка идет первой, поэтому код может быть не выполнен).</p>
+
+<p>Перепишем наш пример с кошками, чтобы использовать цикл <code>do...while</code>:</p>
+
+<pre class="brush: js notranslate">var i = 0;
+
+do {
+ if (i === cats.length - 1) {
+ info += 'and ' + cats[i] + '.';
+ } else {
+ info += cats[i] + ', ';
+ }
+
+ i++;
+} while (i &lt; cats.length);</pre>
+
+<div class="note">
+<p><strong>Примечание: </strong>И снова это работает так же, как и ожидалось - посмотрите, как он работает <a href="http://mdn.github.io/learning-area/javascript/building-blocks/loops/do-while.html">на GitHub</a> (также посмотрите полный <a href="https://github.com/ConstantineZz/javaScript/blob/master/do-while.html">исходный код</a>).</p>
+</div>
+
+<div class="warning">
+<p><strong>Замечание</strong>: Применяя циклы <code>while</code> and <code>do...while</code> , как и все циклы, убедитесь, что инициализатор повторяется так, чтобы он в конце концов достиг условия выхода. Если это не так, цикл будет продолжаться вечно, и либо браузер заставит его остановиться, либо произойдет сбой. Это называется <em><s>доктор Стрэндж и Дормамму</s></em> <strong>бесконечным циклом</strong>. </p>
+</div>
+
+<h2 id="Практическое_упражнение_запускаем_обратный_отсчет!">Практическое упражнение:  запускаем обратный отсчет!</h2>
+
+<p>В этом упражнении мы хотим, чтобы вы написали простой отсчет времени запуска до поля вывода, от 10 до "Пуск!"  В частности, мы хотим, чтобы вы:</p>
+
+<ul>
+ <li>Цикл от 10 до 0. Мы предоставляем вам инициализатор: <code>var i = 10;</code>.</li>
+ <li>Для каждой итерации создайте новый абзац и добавьте его к выходному элементу <code>&lt;div&gt;</code>, который мы выбрали, используя <code>var output = document.querySelector ('.output');</code>. В комментариях мы предоставили вам три строки кода, которые необходимо использовать где-то внутри цикла:
+ <ul>
+ <li><code>var para = document.createElement('p');</code> — создать новый абзац.</li>
+ <li><code>output.appendChild(para);</code> — добавляет абзац к выводу <code>&lt;div&gt;</code>.</li>
+ <li><code>para.textContent =</code> — делает текст внутри абзаца равным значению, которое вы расположили справа, после знака равенства.</li>
+ </ul>
+ </li>
+ <li>Разные номера итераций требуют, чтобы в абзаце для каждой итерации помещался свой текст (вам понадобится условный оператор и несколько<code> para.textContent = lines</code><br>
+ ):
+ <ul>
+ <li>Если число равно 10, выведите в абзаце «Обратный отсчет 10».</li>
+ <li>Если число равно 0, выведите в абзаце «Пуск!»</li>
+ <li>Для любого другого числа выведите в абзаце только число.</li>
+ </ul>
+ </li>
+ <li>Не забудьте включить итератор! Однако в этом примере мы ведем обратный отсчет после каждой итерации, а не вверх, поэтому вам <strong>не</strong> нужен <code>i ++</code>. Как выполнить итерацию вниз?</li>
+</ul>
+
+<p>Если вы допустили ошибку, вы всегда можете сбросить пример с помощью кнопки «Сброс» (Reset). Если у вас совсем ничего не получается, нажмите «Show solution», чтобы увидеть решение.</p>
+
+<div class="hidden">
+<h6 id="Active_learning">Active learning</h6>
+
+<pre class="brush: html notranslate">&lt;h2&gt;Live output&lt;/h2&gt;
+&lt;div class="output" style="height: 410px;overflow: auto;"&gt;
+
+&lt;/div&gt;
+
+&lt;h2&gt;Editable code&lt;/h2&gt;
+&lt;p class="a11y-label"&gt;Press Esc to move focus away from the code area (Tab inserts a tab character).&lt;/p&gt;
+&lt;textarea id="code" class="playable-code" style="height: 300px;width: 95%"&gt;
+var output = document.querySelector('.output');
+output.innerHTML = '';
+
+// var i = 10;
+
+// var para = document.createElement('p');
+// para.textContent = ;
+// output.appendChild(para);
+&lt;/textarea&gt;
+
+&lt;div class="playable-buttons"&gt;
+ &lt;input id="reset" type="button" value="Reset"&gt;
+ &lt;input id="solution" type="button" value="Show solution"&gt;
+&lt;/div&gt;
+</pre>
+
+<p class="brush: js"></p>
+
+<p class="brush: js"></p>
+
+<p class="brush: js"></p>
+
+<pre class="brush: css notranslate">html {
+ font-family: sans-serif;
+}
+
+h2 {
+ font-size: 16px;
+}
+
+.a11y-label {
+ margin: 0;
+ text-align: right;
+ font-size: 0.7rem;
+ width: 98%;
+}
+
+body {
+ margin: 10px;
+ background: #f5f9fa;
+}</pre>
+
+<p class="brush: js"></p>
+
+<p class="brush: js"></p>
+
+<p class="brush: js"></p>
+
+<p class="brush: js"></p>
+
+<pre class="brush: js notranslate">var textarea = document.getElementById('code');
+var reset = document.getElementById('reset');
+var solution = document.getElementById('solution');
+var code = textarea.value;
+var userEntry = textarea.value;
+
+function updateCode() {
+ eval(textarea.value);
+}
+
+reset.addEventListener('click', function() {
+ textarea.value = code;
+ userEntry = textarea.value;
+ solutionEntry = jsSolution;
+ solution.value = 'Show solution';
+ updateCode();
+});
+
+solution.addEventListener('click', function() {
+ if(solution.value === 'Show solution') {
+ textarea.value = solutionEntry;
+ solution.value = 'Hide solution';
+ } else {
+ textarea.value = userEntry;
+ solution.value = 'Show solution';
+ }
+ updateCode();
+});
+
+var jsSolution = 'var output = document.querySelector(\'.output\');\noutput.innerHTML = \'\';\n\nvar i = 10;\n\nwhile(i &gt;= 0) {\n var para = document.createElement(\'p\');\n if(i === 10) {\n para.textContent = \'Countdown \' + i;\n } else if(i === 0) {\n para.textContent = \'Blast off!\';\n } else {\n para.textContent = i;\n }\n\n output.appendChild(para);\n\n i--;\n}';
+var solutionEntry = jsSolution;
+
+textarea.addEventListener('input', updateCode);
+window.addEventListener('load', updateCode);
+
+// stop tab key tabbing out of textarea and
+// make it write a tab at the caret position instead
+
+textarea.onkeydown = function(e){
+ if (e.keyCode === 9) {
+ e.preventDefault();
+ insertAtCaret('\t');
+ }
+
+ if (e.keyCode === 27) {
+ textarea.blur();
+ }
+};
+
+function insertAtCaret(text) {
+ var scrollPos = textarea.scrollTop;
+ var caretPos = textarea.selectionStart;
+
+ var front = (textarea.value).substring(0, caretPos);
+ var back = (textarea.value).substring(textarea.selectionEnd, textarea.value.length);
+ textarea.value = front + text + back;
+ caretPos = caretPos + text.length;
+ textarea.selectionStart = caretPos;
+ textarea.selectionEnd = caretPos;
+ textarea.focus();
+ textarea.scrollTop = scrollPos;
+}
+
+// Update the saved userCode every time the user updates the text area code
+
+textarea.onkeyup = function(){
+ // We only want to save the state when the user code is being shown,
+ // not the solution, so that solution is not saved over the user code
+ if(solution.value === 'Show solution') {
+ userEntry = textarea.value;
+ } else {
+ solutionEntry = textarea.value;
+ }
+
+ updateCode();
+};</pre>
+
+<p class="brush: js"></p>
+</div>
+
+<p>{{ EmbedLiveSample('Active_learning', '100%', 880, "", "", "hide-codepen-jsfiddle") }}</p>
+
+<h2 id="Практическое_упражнение_Заполнение_списка_гостей">Практическое упражнение:   Заполнение списка гостей</h2>
+
+<p>Возьмите список имен, хранящихся в массиве, и поместите их в список гостей. Тут не всё так просто: мы не хотим приглашать Фила и Лолу, потому что они наглые и всё сожрут! У нас есть два списка. Один для тех, кого мы хотим пригласить, второй для тех, кого приглашать не нужно.</p>
+
+<p>Для этого нужно сделать следующее:</p>
+
+<ul>
+ <li>Напишите цикл, который будет повторяться от 0 до длины массива <code>people</code>.<br>
+ Вам нужно начать с инициализатора <code>var i = 0;</code> , но какое нужно использовать условие выхода?</li>
+ <li>Во время каждой итерации цикла нужно проверять, соответствует ли текущий элемент массива именам "Фил" или "Лола", используя условный оператор:
+ <ul>
+ <li>Если это так, привяжите этот элемент массива в конец <code>textContent</code> абзаца <code>refused</code>, за которым следуют запятая и пробел. </li>
+ <li>Если это не так, привяжите этот элемент массива в конец <code>textContent</code> абзаца <code>admitted</code>, за которым следуют запятая и пробел.</li>
+ </ul>
+ </li>
+</ul>
+
+<p>Мы уже предоставили вам:</p>
+
+<ul>
+ <li><code>var i = 0;</code> — Ваш инициализатор.</li>
+ <li><code>refused.textContent +=</code> — начало строки, которая объединит что-то до конца <code>refused.textContent</code>.</li>
+ <li><code>admitted.textContent +=</code> — начало строки, которая объединит что-то до конца <code>admitted.textContent</code>.</li>
+</ul>
+
+<p>Дополнительный бонусный вопрос - после успешного выполнения вышеупомянутых задач у вас останется два списка имен, разделенных запятыми, но они будут составлены некорректно: в конце каждого списка будет запятая. Сможете ли вы составить эти списки так, чтобы в конце каждой строки вместо запятой была точка. За помощью можно обратиться к статье «<a href="/ru/docs/Learn/JavaScript/Первые_шаги/Useful_string_methods">Полезные строковые методы</a>».</p>
+
+<p>Если вы допустили ошибку, вы всегда можете сбросить пример с помощью кнопки «Сброс» (Reset). Если у вас совсем ничего не получается, нажмите «Показать решение», чтобы увидеть решение.</p>
+
+<div class="hidden">
+<h6 id="Active_learning_2">Active learning 2</h6>
+
+<pre class="brush: html notranslate">&lt;h2&gt;Live output&lt;/h2&gt;
+&lt;div class="output" style="height: 100px;overflow: auto;"&gt;
+ &lt;p class="admitted"&gt;Пригласить: &lt;/p&gt;
+  &lt;p class="refused"&gt;Не приглашать(!): &lt;/p&gt;
+&lt;/div&gt;
+
+&lt;h2&gt;Editable code&lt;/h2&gt;
+&lt;p class="a11y-label"&gt;Press Esc to move focus away from the code area (Tab inserts a tab character).&lt;/p&gt;
+&lt;textarea id="code" class="playable-code" style="height: 400px;width: 95%"&gt;
+var people = ['Крис', 'Анна', 'Колин', 'Терри', 'Фил', 'Лола', 'Сем', 'Кай', 'Брюс'];
+
+var admitted = document.querySelector('.admitted');
+var refused = document.querySelector('.refused');
+admitted.textContent = 'Пригласить: ';
+refused.textContent = 'Не приглашать(!): '
+
+// var i = 0;
+
+// refused.textContent += ;
+// admitted.textContent += ;
+
+&lt;/textarea&gt;
+
+&lt;div class="playable-buttons"&gt;
+ &lt;input id="reset" type="button" value="Сброс"&gt;
+ &lt;input id="solution" type="button" value="Показать решение"&gt;
+&lt;/div&gt;
+</pre>
+
+<pre class="brush: css notranslate">html {
+ font-family: sans-serif;
+}
+
+h2 {
+ font-size: 16px;
+}
+
+.a11y-label {
+ margin: 0;
+ text-align: right;
+ font-size: 0.7rem;
+ width: 98%;
+}
+
+body {
+ margin: 10px;
+ background: #f5f9fa;
+}</pre>
+
+<pre class="brush: js notranslate">var textarea = document.getElementById('code');
+var reset = document.getElementById('reset');
+var solution = document.getElementById('solution');
+var code = textarea.value;
+var userEntry = textarea.value;
+
+function updateCode() {
+ eval(textarea.value);
+}
+
+reset.addEventListener('click', function() {
+ textarea.value = code;
+ userEntry = textarea.value;
+ solutionEntry = jsSolution;
+ solution.value = 'Показать решение';
+ updateCode();
+});
+
+solution.addEventListener('click', function() {
+ if(solution.value === 'Показать решение') {
+ textarea.value = solutionEntry;
+ solution.value = 'Скрыть решение';
+ } else {
+ textarea.value = userEntry;
+ solution.value = 'Показать решение';
+ }
+ updateCode();
+});
+
+var jsSolution = 'var people = [\'Крис\', \'Анна\', \'Колин\', \'Терри\', \'Фил\', \'Лола\', \'Сем\', \'Кай\', \'Брюс\'];\n\nvar admitted = document.querySelector(\'.admitted\');\nvar refused = document.querySelector(\'.refused\');\n\nadmitted.textContent = \'Пригласить: \';\nrefused.textContent = \'Не приглашать(!): \'\nvar i = 0;\n\ndo {\n if(people[i] === \'Фил\' || people[i] === \'Лола\') {\n refused.textContent += people[i] + \', \';\n } else {\n admitted.textContent += people[i] + \', \';\n }\n i++;\n} while(i &lt; people.length);\n\nrefused.textContent = refused.textContent.slice(0,refused.textContent.length-2) + \'.\';\nadmitted.textContent = admitted.textContent.slice(0,admitted.textContent.length-2) + \'.\';';
+var solutionEntry = jsSolution;
+
+textarea.addEventListener('input', updateCode);
+window.addEventListener('load', updateCode);
+
+// stop tab key tabbing out of textarea and
+// make it write a tab at the caret position instead
+
+textarea.onkeydown = function(e){
+ if (e.keyCode === 9) {
+ e.preventDefault();
+ insertAtCaret('\t');
+ }
+
+ if (e.keyCode === 27) {
+ textarea.blur();
+ }
+};
+
+function insertAtCaret(text) {
+ var scrollPos = textarea.scrollTop;
+ var caretPos = textarea.selectionStart;
+
+ var front = (textarea.value).substring(0, caretPos);
+ var back = (textarea.value).substring(textarea.selectionEnd, textarea.value.length);
+ textarea.value = front + text + back;
+ caretPos = caretPos + text.length;
+ textarea.selectionStart = caretPos;
+ textarea.selectionEnd = caretPos;
+ textarea.focus();
+ textarea.scrollTop = scrollPos;
+}
+
+// Update the saved userCode every time the user updates the text area code
+
+textarea.onkeyup = function(){
+ // We only want to save the state when the user code is being shown,
+ // not the solution, so that solution is not saved over the user code
+ if(solution.value === 'Show solution') {
+ userEntry = textarea.value;
+ } else {
+ solutionEntry = textarea.value;
+ }
+
+ updateCode();
+};</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Active_learning_2', '100%', 680) }}</p>
+
+<h2 id="Так_какой_тип_цикла_использовать">Так какой тип цикла использовать?</h2>
+
+<p>В основном, используют <code>for</code>, <code>while</code> и <code>do...while</code> циклы, и они во многом взаимозаменяемы. Все они могут быть использованы для выполнения одних и тех же задач и какой из них вы будете использовать, во многом зависит от ваших личных предпочтений. Используйте тот, который вам проще всего запомнить или наиболее интуитивно понятен. Давайте вспомним каждый из них.</p>
+
+<p><strong><code>For</code></strong>:</p>
+
+<pre class="notranslate">for (initializer; exit-condition; final-expression) {
+ // code to run
+}</pre>
+
+<p><strong><code>while</code></strong>:</p>
+
+<pre class="notranslate">initializer
+while (exit-condition) {
+ // code to run
+
+ final-expression
+}</pre>
+
+<p><strong><code>do...while</code></strong>:</p>
+
+<pre class="notranslate">initializer
+do {
+ // code to run
+
+ final-expression
+} while (exit-condition)</pre>
+
+<p>Для начала мы бы порекомендовали <code>for</code>, так как его проще запомнить: инициализатор, условие выхода и конечное выражение аккуратно заключено в скобки, поэтому их легко отследить, чтобы их не пропускать.</p>
+
+<div class="note">
+<p><strong>Примечание. </strong>Существуют и другие типы и функции цикла, которые полезны в сложных или специализированных ситуациях и выходят за рамки данной статьи. Если вы хотите подробнее изучить тему циклов, прочитайте наше расширенное<a href="/ru/docs/Web/JavaScript/Guide/Циклы_и_итерации"> руководство по циклам и итерациям.</a> </p>
+</div>
+
+<h2 id="Заключение">Заключение</h2>
+
+<p>Эта статья раскрывает основные концепции и различные опции, доступные при циклическом кодировании в JavaScript. Теперь вам должно быть понятно, почему циклы являются хорошим механизмом для работы с повторяющимся кодом. Старайтесь использовать их в своих собственных примерах!</p>
+
+<p>Если вы чего-то не поняли, пробуйте читать статью снова или <a href="/ru/docs/Learn#Связаться_с_нами">свяжитесь с нами</a>, мы поможем разобраться.</p>
+
+<h2 id="Дополнительная_информация">Дополнительная информация</h2>
+
+<ul>
+ <li><a href="/ru/docs/Web/JavaScript/Guide/Циклы_и_итерации">Циклы и итерации</a></li>
+ <li><a href="/ru/docs/Web/JavaScript/Reference/Statements/for">for свойства и характеристики</a></li>
+ <li><a href="/ru/docs/Web/JavaScript/Reference/Statements/while">while</a> и <a href="/ru/docs/Web/JavaScript/Reference/Statements/do...while">do...while</a> описание</li>
+ <li><a href="/ru/docs/Web/JavaScript/Reference/Statements/break">break</a> и <a href="/ru/docs/Web/JavaScript/Reference/Statements/continue">continue</a> описание</li>
+ <li>
+ <p class="entry-title"><a href="https://www.impressivewebs.com/javascript-for-loop/">What’s the Best Way to Write a JavaScript For Loop?</a> — статья о практическом применении циклов</p>
+ </li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/conditionals","Learn/JavaScript/Building_blocks/Functions", "Learn/JavaScript/Building_blocks")}}</p>
+
+<h2 id="В_этом_модуле">В этом модуле</h2>
+
+<ul>
+ <li><a href="/ru/docs/Learn/JavaScript/Building_blocks/conditionals">Принятие решений в Вашем коде — условные конструкции</a></li>
+ <li><a href="/ru/docs/Learn/JavaScript/Building_blocks/Looping_code">Зацикливание кода</a></li>
+ <li><a href="/ru/docs/Learn/JavaScript/Building_blocks/Functions">Функции — Переиспользуемые блоки кода</a></li>
+ <li><a href="/ru/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">Создайте свою собственную функцию</a></li>
+ <li><a href="/ru/docs/Learn/JavaScript/Building_blocks/Return_values">Возвращаемое значение функции</a></li>
+ <li><a href="/ru/docs/Learn/JavaScript/Building_blocks/События">Введение в события</a></li>
+ <li><a href="/ru/docs/Learn/JavaScript/Building_blocks/Image_gallery">Создание галереи</a></li>
+</ul>
diff --git a/files/ru/learn/javascript/building_blocks/return_values/index.html b/files/ru/learn/javascript/building_blocks/return_values/index.html
new file mode 100644
index 0000000000..016321c969
--- /dev/null
+++ b/files/ru/learn/javascript/building_blocks/return_values/index.html
@@ -0,0 +1,172 @@
+---
+title: Возвращаемое значение функции
+slug: Learn/JavaScript/Building_blocks/Return_values
+translation_of: Learn/JavaScript/Building_blocks/Return_values
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Build_your_own_function","Learn/JavaScript/Building_blocks/События", "Learn/JavaScript/Building_blocks")}}</div>
+
+<p class="summary">Для нас в этом курсе имеется еще один важный момент. Посмотрим внимательнее на возвращаемое значение функций. Некоторые функции не возвращают существенное значение после завершения, но некоторые возвращают, и важно понимать что это за значение и как использовать его в своем коде и как сделать так чтобы ваши собственные функции возвращали полезные значения. Мы объясним всё это ниже. </p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Необходимые навыки:</th>
+ <td>
+ <p>Базовая компьютерная грамотность, знание основ HTML и CSS, <a href="/en-US/docs/Learn/JavaScript/First_steps">JavaScript first steps</a>, <a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions">Functions — reusable blocks of code</a>.</p>
+ </td>
+ </tr>
+ <tr>
+ <th scope="row">Цели:</th>
+ <td>Понять что такое возвращаямое значение функции и как его использовать.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Что_из_себя_представляют_возвращаемые_значения">Что из себя представляют возвращаемые значения?</h2>
+
+<p><strong>Возвращаемые значения </strong>- это на самом деле просто значения, которые функция возвращает после своего завершения. Вы уже неоднократно встречали возвращаемые значения, хотя, возможно, и не осознавали этого. Напишем небольшой код: </p>
+
+<pre class="brush: js">var myText = 'I am a string';
+var newString = myText.replace('string', 'sausage');
+console.log(newString);
+// функция replace() принимает строку,
+// заменяет одну подстроку другой и возвращает
+// новую строку со сделанными заменами</pre>
+
+<p>Мы уже видели этот блок кода в нашей первой статье про функции. Мы вызываем функцию <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace">replace()</a> на строке <code>myText</code> и передаем ей 2 параметра —  заменяемую подстроку и подстроку, которой будем заменять. Когда функция завершит выполнение, она вернет значение, которым является новая строка со сделанными в ней заменами.  В коде выше мы сохраняем это возвращаемое значение как значение переменной <code>newString</code>.</p>
+
+<p>Если Вы посмотрите на функцию replace() на MDN reference page, вы увидите секцию под названием <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Return_value">Return value</a>.  Очень важно знать и понимать какие значения возвращаются функциями, так что мы пытаемся включать эту информацию везде, где это возможно.</p>
+
+<p>Некоторые функции не возвращают значения( на наших reference pages, возвращаемое значение обозначено как <code>void</code> или <code>undefined</code> в таких случаях). Например, в функции <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/functions/function-stage-4.html#L50">displayMessage()</a> которую мы сделали в прошлой статье, в результате выполнения функции не возвращается никакого значения. Функция всего лишь отображает что-то где-то на экране.</p>
+
+<p>В основном, возвращаемое значение используется там, где функция является чем-то вроде вспомогательного звена при вычислениях. Вы хотите получить результат, который включает в себя некоторые значения. Эти значения вычисляются функцией, которая возвращает результат так, что он может быть использован в следующих стадиях вычисления.</p>
+
+<h3 id="Использование_возвращаемых_значений_в_ваших_собственных_функциях">Использование возвращаемых значений в ваших собственных функциях</h3>
+
+<p>Чтобы вернуть значение своей функции, вы должны использовать ключевое слово <a href="/en-US/docs/Web/JavaScript/Reference/Statements/return">return</a>. Мы видели это в действии недавно - в нашем примере <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/random-canvas-circles.html">random-canvas-circles.html</a>. Наша функция<code>draw()</code>отрисовывает где-то на экране 100 случайных кружков. </p>
+
+<p>{{htmlelement("canvas")}}:</p>
+
+<pre class="brush: js">function draw() {
+ ctx.clearRect(0,0,WIDTH,HEIGHT);
+ for (var i = 0; i &lt; 100; i++) {
+ ctx.beginPath();
+ ctx.fillStyle = 'rgba(255,0,0,0.5)';
+ ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI);
+ ctx.fill();
+ }
+}</pre>
+
+<p>Внутри каждой итерации есть 3 вызова функции <code>random()</code>. Это сделано чтобы сгенерировать случайное значение для текущей координаты x, y и для радиуса. Функция <code>random()</code> принимает 1 параметр (целое число) и возвращает случайное число в диапазоне от 0 до этого числа. Выглядит это вот так: </p>
+
+<pre class="brush: js">function random(number) {
+ return Math.floor(Math.random()*number);
+}</pre>
+
+<p>Тоже самое может быть написано вот так:</p>
+
+<pre class="brush: js">function random(number) {
+ var result = Math.floor(Math.random()*number);
+ return result;
+}</pre>
+
+<p>Но первую версию написать быстрее и она более компактна.</p>
+
+<p>Мы возвращаем результат вычисления <code>Math.floor(Math.random()*number)</code> каждый раз когда функция вызывается. Это возвращаемое значение появляется в момент вызова функции и код продолжается. Так, например, если мы выполним следующую строчку:</p>
+
+<pre class="brush: js">ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI);</pre>
+
+<p>и 3 вызова <code>random()</code> вернут значения 500, 200 и 35, соответственно, строчка будет выполнена как если бы она была такой:</p>
+
+<pre class="brush: js">ctx.arc(500, 200, 35, 0, 2 * Math.PI);
+</pre>
+
+<p>Сначала выполняются вызовы функции <code>random()</code>, на место которых подставляются возвращаемые ей значения, а затем выполнятся сама строка.</p>
+
+<h2 id="Активное_обучение_наша_собственная_возвращающая_значение_функция">Активное обучение: наша собственная, возвращающая значение функция</h2>
+
+<p>Теперь напишем нашу собственную возвращающую значение функцию.</p>
+
+<ol>
+ <li>Первым делом, сделайте локальную копию файла <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/functions/function-library.html">function-library.html</a> из GitHub. Это простая HTML страничка, содержащая текстовое поле {{htmlelement("input")}} и параграф Также там есть элемент {{htmlelement("script")}} в котором мы храним в 2ух переменных ссылки на оба HTML элемента. Это маленькая страничка позволит Вам ввести число в text box и отобразит различные, относящиеся к нему числа в параграфе ниже.</li>
+ <li>Теперь добавим несколько полезных функций в элемент <code>&lt;script&gt;</code> . Ниже двух существующих строчек JavaScript, добавьте следующие описания функций:
+ <pre class="brush: js">function squared(num) {
+ return num * num;
+}
+
+function cubed(num) {
+ return num * num * num;
+}
+
+function factorial(num) {
+ var x = num;
+ while (x &gt; 1) {
+ num *= x-1;
+ x--;
+ }
+ return num;
+}</pre>
+ <code>Ф</code>ункции <code>squared()</code> и <code>cubed()</code> довольно очевидны— они возвразают квадрат или куб переданного как параметр числа. Функция <code>factorial()</code> возвращает <a href="https://en.wikipedia.org/wiki/Factorial">factorial</a> переданного числа.</li>
+ <li>Далее мы добавим способ выводить нашу информацию введенным в  text input числе. Добавьте обработчик событий ниже существующих функций:
+ <pre class="brush: js">input.onchange = function() {
+ var num = input.value;
+ if (isNaN(num)) {
+ para.textContent = 'You need to enter a number!';
+ } else {
+ para.textContent = num + ' squared is ' + squared(num) + '. ' +
+ num + ' cubed is ' + cubed(num) + '. ' +
+ num + ' factorial is ' + factorial(num) + '.';
+ }
+}</pre>
+
+ <p>Здесь мы создаем обработчик событий <code>onchange</code>  который срабатывает когда меняется когда новое значение вводится в text input и подтверждается (введите значение и, например, нажмите tab). Когда анонимная функция срабатывает, введенное в input значение сохраняется в переменной <code>num</code> .</p>
+ </li>
+ <li>
+ <p>Далее мы делаем условный тест — если введенное значение не является чилом, мы выводим в параграф сообщение об ошибке . Тест смотрит возвращает ли выражение <code>isNaN(num)</code>  true. Мы используем функцию <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN">isNaN()</a> чтобы проверить что значение переменной num не число — если так то функция возвращает<code>true</code>, если нет- <code>false</code>.</p>
+ </li>
+ <li>
+ <p>Если тест возвращает <code>false</code>, значение переменной <code>num</code>число, и поэтому мы выводим сообщение внутри параграфа о значениях квадрата, куба и факториала числа. Предложение вызывает  функции <code>squared()</code>, <code>cubed()<font face="Open Sans, arial, x-locale-body, sans-serif"><span style="background-color: #ffffff;"> и</span></font></code><code>factorial()</code> чтобы получить нужные значения. Сохраните Ваш код, загрузите его в браузере и посмотрите на то что получилось.</p>
+ </li>
+</ol>
+
+<div class="note">
+<p><strong>Замечание</strong>:  Если у вас проблемы с работой данного примера, не стесняйтесь сверить ваш код с работающей версией <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/functions/function-library-finished.html">finished version on GitHub</a> (или <a href="http://mdn.github.io/learning-area/javascript/building-blocks/functions/function-library-finished.html">смотрите живой пример</a>), или спросите нас.</p>
+</div>
+
+<p>К этому моменту мы хотели бы чтобы вы написали парочку собственных функций и добавили их в библиотеку. Как на счет квадратного или кубического корня числа или длины окружности круга с длиной радиуса равной числу <code>num</code>?</p>
+
+<p>Это упражнение привнесло парочку важных понятий в изучении того, как использовать ключевое слово <code>return</code> . В дополнение:</p>
+
+<ul>
+ <li>Приведите другой пример написание обработчика ошибок. Это довольно хорошая идея проверять что важные параметры предоставлены в правильном типе и если они опциональны то предусматривать для них значения по умолчанию. В таком случая Ваша программа с меньшей вероятность подвержена ошибкам. </li>
+ <li>Поразмышляйте о идее создания библиотеки функций. Чем дальше Вы будите расти в профессиональном плане, тем больше будете сталкиваться с однотипными вещами. Это хорошая идея начать собирать свою собственную библиотеку функций, которые Вы часто используюте — в таком случае Вы сможете просто скопировать их в Ваш новый код или просто добавить их в любую HTML страничку, где это требуется.</li>
+</ul>
+
+<h2 id="Заключение">Заключение</h2>
+
+<p>Функции очень полезны и не смотря на то, что об их синтаксисе и функциональности можно говорить долго, у нас есть довольно понятные статьи для дальнейшего обучения.</p>
+
+<p>Если в статье есть что-то что вы не поняли, не стесняйтесь перечитать статью еще раз или <a href="/en-US/Learn#Contact_us">свяжитесь с нами</a> для получения помощи.</p>
+
+<h2 id="Смотрите_также">Смотрите также</h2>
+
+<ul>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions">Функции более подробно</a> — подробное руководство, охватывающее более продвинутую информацию, связанную с функциями.</li>
+ <li><a href="https://www.impressivewebs.com/callback-functions-javascript/">Функции обратного вызова в JavaScript</a> — распространенный паттерн JavaScript для передачи функции в другую функцию как аргумент, который затем вызывается внутри первой функици.</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Build_your_own_function","Learn/JavaScript/Building_blocks/Events", "Learn/JavaScript/Building_blocks")}}</p>
+
+<h2 id="In_this_module">In this module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/conditionals">Making decisions in your code — conditionals</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code">Looping code</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions">Functions — reusable blocks of code</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">Build your own function</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Return_values">Function return values</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events">Introduction to events</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Image_gallery">Image gallery</a></li>
+</ul>
diff --git a/files/ru/learn/javascript/building_blocks/test_your_skills_colon__functions/index.html b/files/ru/learn/javascript/building_blocks/test_your_skills_colon__functions/index.html
new file mode 100644
index 0000000000..62e1951fdc
--- /dev/null
+++ b/files/ru/learn/javascript/building_blocks/test_your_skills_colon__functions/index.html
@@ -0,0 +1,99 @@
+---
+title: 'Проверь свои навыки: Функции'
+slug: 'Learn/JavaScript/Building_blocks/Test_your_skills:_Functions'
+tags:
+ - JavaScript
+ - Изучение
+ - Новичек
+ - Функции
+translation_of: 'Learn/JavaScript/Building_blocks/Test_your_skills:_Functions'
+---
+<div>{{learnsidebar}}</div>
+
+<p>Целью данного теста навыков является оценка понимания таких статей, как: <a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions">Функций — многократное использование блоков кода</a>, <a href="/en-US/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">Построение своих собственных функций</a> и <a href="/en-US/docs/Learn/JavaScript/Building_blocks/Return_values">Возвращаемые значения функции</a>.</p>
+
+<div class="blockIndicator note">
+<p>Примечание: Вы можете проверить решения в интерактивных редакторах ниже, однако может быть полезно загрузить код и использовать онлайн-инструменты, такие как <a href="https://codepen.io/">CodePen</a>, <a href="https://jsfiddle.net/">jsFiddle</a> или <a href="https://glitch.com/">Glitch</a> для работы над задачами.<br>
+ <br>
+ Если у вас возникла проблема, то попросите нас о помощи - см. раздел {{anch("Анализ или дальнейшая помощь")}} внизу этой страницы.</p>
+</div>
+
+<div class="blockIndicator note">
+<p>Примечание: В примерах ниже, если в вашем коде есть ошибка, она будет выведена на панель результатов этой страницы, чтобы помочь вам попытаться выяснить ответ (или в JavaScript консоли браузера, в случае загружаемой версии).</p>
+</div>
+
+<h2 id="Управление_структурой_DOM_рекомендуется">Управление структурой DOM: рекомендуется</h2>
+
+<p>Некоторые из вопросов, приведенных ниже, требуют написания кода для управления структурой <a href="/en-US/docs/Glossary/DOM">DOM</a> для их решения - например, создание новых HTML-элементов, установка их текстового содержимого в соответствие с определенными значениями строк, и вложение их внутри существующих элементов на странице - и все это с помощью JavaScript.</p>
+
+<p>Мы еще не обучали этому прямо в курсе, но вы увидите некоторые примеры, которые используют данную структуру, и мы хотели бы, чтобы вы провели некоторые исследования в отношении того, какие DOM API вам нужны, чтобы успешно ответить на эти вопросы. Хорошим началом будет наше учебное пособие <a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Manipulating_documents">Управление документами</a>.</p>
+
+<h2 id="Функции_1">Функции 1</h2>
+
+<p>Для решения первой задачи вам нужно создать простую функцию — <code>chooseName()</code>, которая выполнит выборку случайного имени из данного массива (<code>names</code>) и выведет его в предоставленный параграф (<code>para</code>). А затем необходимо запустить эту функцию один раз.</p>
+
+<p>Попробуйте обновить рабочий код ниже, чтобы воссоздать готовый пример:</p>
+
+<p>{{EmbedGHLiveSample("learning-area/javascript/building-blocks/tasks/functions/functions1.html", '100%', 400)}}</p>
+
+<div class="blockIndicator note">
+<p><a href="https://github.com/mdn/learning-area/tree/master/javascript/building-blocks/tasks/functions/functions1-download.html">Загрузите файл с исходным кодом для этой задачи</a> для работы в собственном редакторе или в онлайн-редакторе.</p>
+</div>
+
+<h2 id="Функции_2">Функции 2</h2>
+
+<p>Для решения второй задачи, связанной с функциями, необходимо создать функцию, которая рисует прямоугольник на заданном элементе <code>&lt;canvas&gt;</code> (исходная переменная <code>canvas</code>, контекст доступен в <code>ctx</code>), основанном на пяти предоставленных входящих значениях:</p>
+
+<ul>
+ <li><code>x</code> — x координата прямоугольника.</li>
+ <li><code>y</code> — y координата прямоугольника.</li>
+ <li><code>width</code> — ширина прямоугольника.</li>
+ <li><code>height</code> — высота прямоугольника.</li>
+ <li><code>color</code> — цвет прямоугольника.</li>
+</ul>
+
+<p>Перед рисованием вам нужно будет очистить содержимое элемента canvas , чтобы при обновлении кода в случае с рабочей версией, вы не получили много прямоугольников, находящихся друг на друге.</p>
+
+<p>Попробуйте обновить рабочий код ниже, чтобы воссоздать готовый пример:</p>
+
+<p>{{EmbedGHLiveSample("learning-area/javascript/building-blocks/tasks/functions/functions2.html", '100%', 400)}}</p>
+
+<div class="blockIndicator note">
+<p><a href="https://github.com/mdn/learning-area/tree/master/javascript/building-blocks/tasks/functions/functions2-download.html">Загрузите файл с исходным кодом для этой задачи</a> для работы в собственном редакторе или в онлайн-редакторе.</p>
+</div>
+
+<h2 id="Функции_3">Функции 3</h2>
+
+<p>В этой задаче вы возвращаетесь к проблеме, поставленной в Задаче 1, с целью ее улучшения. Мы хотим, чтобы вы сделали три улучшения:</p>
+
+<ol>
+ <li>Выполните рефакторинг (реорганизацию) кода, который отвечает за генерацию случайного числа в отдельную функцию <code>random()</code>, которая принимает в качестве параметров две общие границы, между которыми должно находиться случайное число и возвращает результат.</li>
+ <li>Обновите функцию <code>chooseName()</code> таким образом, чтобы она использовала функцию случайных чисел, принимала массив для выбора в качестве параметра (что делает его более гибким) и возвращала результат.</li>
+ <li>Вывести возвращаемый результат в параграф (<code>para</code>) с помощью свойства <code>textContent</code>. </li>
+</ol>
+
+<p>Попробуйте обновить рабочий код ниже, чтобы воссоздать готовый пример:</p>
+
+<p>{{EmbedGHLiveSample("learning-area/javascript/building-blocks/tasks/functions/functions3.html", '100%', 400)}}</p>
+
+<div class="blockIndicator note">
+<p><a href="https://github.com/mdn/learning-area/tree/master/javascript/building-blocks/tasks/functions/functions3-download.html">Загрузите файл с исходным кодом для этой задачи</a> для работы в собственном редакторе или в онлайн-редакторе.</p>
+</div>
+
+<h2 id="Анализ_или_дальнейшая_помощь">Анализ или дальнейшая помощь</h2>
+
+<p>Вы можете попрактиковаться на этих примерах в интерактивных редакторах выше.</p>
+
+<p>Если же вы хотите, чтобы вашу работу проанализировали, или у вас проблема и вы хотите попросить о помощи:</p>
+
+<ol>
+ <li>Поместите свой код в онлайн-редактор <a href="https://codepen.io/">CodePen</a>, <a href="https://jsfiddle.net/">jsFiddle</a> или <a href="https://glitch.com/">Glitch</a> с возможностью совместного использования. Вы можете написать код самостоятельно или использовать файлы с исходным кодом, ссылки на которые приведены в вышеприведенных разделах.</li>
+ <li>Напишите сообщение с просьбой о проведении анализа и/или помощи в категории <a href="https://discourse.mozilla.org/c/mdn/learn">MDN Discourse forum Learning category</a>. Ваше сообщение должно включать в себя следующие пункты:
+ <ul>
+ <li>Описательный заголовок, например "Анализ для теста навыков: Функции 1".</li>
+ <li>Детали того, что вы уже пробовали, и что бы вы хотели, чтобы мы сделали, например, если вы застряли и нуждаетесь в помощи, или хотите получить анализ проблемы.</li>
+ <li>Ссылка на пример, который вы хотели бы рассмотреть или с которым вам нужна помощь, в онлайн-редакторе, доступном для совместного использования (как упоминалось в шаге 1 выше). Это хорошая практика - очень сложно помочь кому-то с проблемой, если вы не видите его код.</li>
+ <li>Ссылка на фактическую задачу или страницу рассмотрения проблемы, чтобы мы могли найти вопрос, по которому вам нужна помощь.</li>
+ </ul>
+ </li>
+</ol>
diff --git a/files/ru/learn/javascript/building_blocks/события/index.html b/files/ru/learn/javascript/building_blocks/события/index.html
new file mode 100644
index 0000000000..db13cec676
--- /dev/null
+++ b/files/ru/learn/javascript/building_blocks/события/index.html
@@ -0,0 +1,606 @@
+---
+title: Введение в события
+slug: Learn/JavaScript/Building_blocks/События
+tags:
+ - Изучение
+ - Обработчик событий
+ - Руководство
+ - события
+translation_of: Learn/JavaScript/Building_blocks/Events
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Return_values","Learn/JavaScript/Building_blocks/Image_gallery", "Learn/JavaScript/Building_blocks")}}</div>
+
+<p class="summary">События — это действия или случаи, возникающие в программируемой вами системе, о которых система сообщает вам для того, чтобы вы могли с ними взаимодействовать. Например, если пользователь нажимает кнопку на веб-странице, вы можете ответить на это действие, отобразив информационное окно. В этой статье мы обсудим некоторые важные концепции, связанные с событиями, и посмотрим, как они работают в браузерах. Эта статья не является исчерпывающим источником по этой теме — здесь только то, что вам нужно знать на этом этапе.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Предпосылки:</th>
+ <td>Базовая компьютерная грамотность, базовое понимание HTML и CSS, <a href="/ru/docs/Learn/JavaScript/Первые_шаги">Первые шаги в JavaScript</a>.</td>
+ </tr>
+ <tr>
+ <th scope="row">Задача:</th>
+ <td>Понять фундаментальную теорию событий, как они работают в браузерах и как события могут различаться в разных средах программирования.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Серия_удачных_событий">Серия удачных событий</h2>
+
+<p>При возникновении <strong>события</strong> система генерирует сигнал, а также предоставляет механизм, с помощью которого можно автоматически предпринимать какие-либо действия (например, выполнить определенный код), когда происходит событие. Например, в аэропорту, когда взлетно-посадочная полоса свободна для взлета самолета, сигнал передается пилоту, и в результате они приступают к взлету.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/17376/MDN-mozilla-events-runway.png" style="height: 443px; width: 700px;"></p>
+
+<p>В Web события запускаются внутри окна браузера и, как правило, прикрепляются к конкретному элементу, который в нем находится. Это может быть один элемент, набор элементов, документ HTML, загруженный на текущей вкладке, или все окно браузера. Существует множество различных видов событий, которые могут произойти, например:</p>
+
+<ul>
+ <li>Пользователь кликает мышью или наводит курсор на определенный элемент.</li>
+ <li>Пользователь нажимает клавишу на клавиатуре.</li>
+ <li>Пользователь изменяет размер или закрывает окно браузера.</li>
+ <li>Завершение загрузки веб-страницы.</li>
+ <li>Отправка данных через формы.</li>
+ <li>Воспроизведение видео, пауза или завершение воспроизведения.</li>
+ <li>Произошла ошибка.</li>
+</ul>
+
+<p>Подробнее о событиях можно посмотреть в <a href="/ru/docs/Web/Events">Справочнике по событиям</a>.</p>
+
+<p><span>Каждое доступное событие имеет </span><strong>обработчик событий<strong> </strong></strong>—<span> блок кода (обычно это функция JavaScript, вводимая вами в качестве разработчика), который будет запускаться при срабатывании события. Когда такой блок кода определен на запуск в ответ на возникновение события, мы говорим, что мы </span><strong>регистрируем обработчик событий</strong><span>. Обратите внимание, что обработчики событий иногда называют </span><strong>прослушивателями событий (event listeners).</strong><span> Они в значительной степени взаимозаменяемы для наших целей, хотя, строго говоря, они работают вместе. Прослушиватель отслеживает событие, а обработчик </span>— <span>это код, который запускается в ответ на событие.</span></p>
+
+<div class="note">
+<p><strong>Примечание:</strong> Важно отметить, что веб-события не являются частью основного языка JavaScript. Они определены как часть JavaScript-API, встроенных в браузер.</p>
+</div>
+
+<h3 id="Простой_пример">Простой пример</h3>
+
+<p>Рассмотрим простой пример. Вы уже видели события и обработчики событий во многих примерах в этом курсе, но давайте повторим для закрепления информации. В этом примере у нас есть кнопка {{htmlelement ("button")}}, при нажатии которой цвет фона изменяется случайным образом:</p>
+
+<pre class="brush: html notranslate">&lt;button&gt;Change color&lt;/button&gt;</pre>
+
+<div class="hidden">
+<pre class="brush: css notranslate">button { margin: 10px };</pre>
+</div>
+
+<p>JavaScript выглядит так:</p>
+
+<pre class="brush: js notranslate">const btn = document.querySelector('button');
+
+function random(number) {
+ return Math.floor(Math.random() * (number+1));
+}
+
+btn.onclick = function() {
+ const rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
+ document.body.style.backgroundColor = rndCol;
+}</pre>
+
+<p>В этом коде мы сохраняем ссылку на кнопку внутри переменной <code>btn</code> типа <code>const</code>, используя функцию {{domxref ("Document.querySelector()")}}. Мы также определяем функцию, которая возвращает случайное число. Третья часть кода — <a href="#Свойства_обработчика_событий">обработчик события</a>. Переменная <code>btn</code> указывает на элемент <code>&lt;button&gt;</code> — для этого типа объекта существуют возникающие при определенном взаимодействии с ним события, а значит, возможно использование обработчиков событий. Мы отслеживаем момент возникновения события при щелчке мышью, связывая свойство обработчика события <code>onclick</code> с анонимной функцией, генерирующей случайный цвет RGB и устанавливающей его в качестве цвета фона элемента <code>&lt;body&gt;</code>.</p>
+
+<p>Этот код теперь будет запускаться всякий раз, когда возникает событие при нажатии на элемент <code>&lt;button&gt;</code> — всякий раз, когда пользователь щелкает по нему.</p>
+
+<p>Пример вывода выглядит следующим образом:</p>
+
+<p>{{ EmbedLiveSample('Простой_пример', '100%', 200, "") }}</p>
+
+<h3 id="События_не_только_для_веб-страниц">События не только для веб-страниц</h3>
+
+<p>События, как понятие, относятся не только к JavaScript — большинство языков программирования имеют модель событий, способ работы которой часто отличается от модели в JavaScript. Фактически, даже модель событий в JavaScript для веб-страниц отличается от модели событий для просто JavaScript, поскольку используются они в разных средах.</p>
+
+<p>Например, <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs">Node.js</a> — очень популярная среда исполнения JavaScript, которая позволяет разработчикам использовать JavaScript для создания сетевых и серверных приложений. <a href="https://nodejs.org/docs/latest-v5.x/api/events.html">Модель событий Node.js</a> основана на том, что существуют прослушиватели, отслеживающие события, и эмиттеры (передатчики), которые периодически генерируют события. В общем-то, это похоже на модель событий в JavaScript для веб-страниц, но код совсем другой. В этой модели используется функция <code>on()</code> для регистрации прослушивателей событий, и функция <code>once()</code> для регистрации прослушивателя событий, который отключается после первого срабтывания. Хорошим примером использования являются протоколы событий <a href="https://nodejs.org/docs/latest-v8.x/api/http.html#http_event_connect">HTTP connect event docs</a>.</p>
+
+<p>Вы также можете использовать JavaScript для создания кросс-браузерных расширений — улучшения функциональности браузера с помощью технологии <a href="https://developer.mozilla.org/ru/docs/Mozilla/Add-ons/WebExtensions">WebExtensions</a>. В отличии от модели веб-событий здесь свойства прослушивателей событий пишутся в так называемом регистре <a href="https://ru.wikipedia.org/wiki/CamelCase">CamelCase</a> (например, <code>onMessage</code>, а не <code>onmessage</code>) и должны сочетаться с функцией <code>addListener</code>. См. <a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/runtime/onMessage#Examples">runtime.onMessage page</a> для примера.</p>
+
+<p>На данном этапе обучения вам не нужно особо разбираться в различных средах программирования, однако важно понимать, что принцип работы <em>событий</em> в них отличается.</p>
+
+<h2 id="Способы_использования_веб-событий">Способы использования веб-событий</h2>
+
+<p>Существует множество различных способов добавления кода прослушивателя событий на веб-страницы так, чтобы он срабатывал при возникновении соответствующего события. В этом разделе мы рассмотрим различные механизмы и обсудим, какие из них следует использовать.</p>
+
+<h3 id="Свойства_обработчика_событий">Свойства обработчика событий</h3>
+
+<p>В этом курсе вы уже сталкивались со свойствами, связываемыми с алгоритмом работы обработчика событий. Вернемся к приведенному выше примеру:</p>
+
+<pre class="brush: js notranslate">const btn = document.querySelector('button');
+
+btn.onclick = function() {
+ var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
+ document.body.style.backgroundColor = rndCol;
+}</pre>
+
+<p>В данной ситауции свойство <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onclick">onclick</a></code> — это свойство обработчика события. В принципе это обычное свойство кнопки как элемента (наравне с <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent">btn.textContent</a></code> или <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style">btn.style</a></code>), но оно относится к особому типу. Если вы установите его равным какому-нибудь коду, этот код будет запущен при возникновении события (при нажатии на кнопку).</p>
+
+<p>Для получения того же результата, Вы также можете присвоить свойству обработчика имя уже описанной функции (как мы видели в статье <a href="/ru/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">Создайте свою функцию</a>):</p>
+
+<pre class="brush: js notranslate">const btn = document.querySelector('button');
+
+function bgChange() {
+ const rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
+ document.body.style.backgroundColor = rndCol;
+}
+
+btn.onclick = bgChange;</pre>
+
+<p>Давайте теперь поэкспериментируем с другими свойствами обработчика событий.</p>
+
+<p>Создайте локальную копию файла <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/random-color-eventhandlerproperty.html">random-color-eventhandlerproperty.html</a> и откройте ее в своем браузере. Это всего лишь копия простого примера про случайные цвета, который мы уже разобрали в этой статье. Теперь попробуйте изменить <code>btn.onclick</code> на следующие значения и понаблюдайте за результатами:</p>
+
+<ul>
+ <li><code><a href="https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onfocus">btn.onfocus</a></code> и <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onblur">btn.onblur</a></code> — Цвет изменится, когда кнопка будет сфокусирована или не сфокусирована (попробуйте нажать Tab, чтобы выбрать кнопку или убрать выбор). Эти свойства часто применяются для отображения информации о том, как заполнить поля формы, когда они сфокусированы, или отобразить сообщение об ошибке, если поле формы было заполнено с неправильным значением.</li>
+ <li><code><a href="/en-US/docs/Web/API/GlobalEventHandlers/ondblclick">btn.ondblclick</a></code> — Цвет будет изменяться только при двойном щелчке.</li>
+ <li><code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onkeypress">window.onkeypress</a></code>, <code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onkeydown">window.onkeydown</a></code>, <code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onkeyup">window.onkeyup</a></code> — Цвет будет меняться при нажатии клавиши на клавиатуре, причём <code>keypress</code> ссылается на обычное нажатие (нажатие кнопки и последующее её отпускание <em>как одно целое</em>), в то время как <code>keydown</code> и <code>keyup</code> <em>разделяют</em> действия на нажатие клавиши и отпускание, и ссылаются на них соответственно. Обратите внимание, что это не работает, если вы попытаетесь зарегистрировать этот обработчик событий на самой кнопке - его нужно зарегистрировать на объекте <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window">window</a>, который представляет все окно браузера.</li>
+ <li><code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onmouseover">btn.onmouseover</a></code> и <code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onmouseout">btn.onmouseout</a></code> — Цвет будет меняться при наведении указателя мыши на кнопку или когда указатель будет отводиться от кнопки соответственно.</li>
+</ul>
+
+<p>Некоторые события очень общие и доступны практически в любом месте (например, обработчик <code>onclick</code> может быть зарегистрирован практически для любого элемента), тогда как некоторые из них более конкретны и полезны только в определенных ситуациях (например, имеет смысл использовать <a href="https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/GlobalEventHandlers.onplay">onplay</a> только для определенных элементов, таких как {{htmlelement ("video")}}).</p>
+
+<h3 id="Встроенные_обработчики_событий_-_не_используйте_их">Встроенные обработчики событий - не используйте их</h3>
+
+<p>Самый ранний из введенных в сеть Web методов регистрации <em>обработчиков событий</em> базируется на <strong>HTML атрибутах </strong>(<strong>встроенные обработчики событий</strong>):</p>
+
+<pre class="brush: html notranslate">&lt;button onclick="bgChange()"&gt;Press me&lt;/button&gt;
+</pre>
+
+<pre class="brush: js notranslate">function bgChange() {
+ const rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
+ document.body.style.backgroundColor = rndCol;
+}</pre>
+
+<div class="note">
+<p><strong>Примечание</strong>: Вы можете найти <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/random-color-eventhandlerattributes.html">полный исходник кода</a> из этого примера на GitHub (также <a href="http://mdn.github.io/learning-area/javascript/building-blocks/events/random-color-eventhandlerattributes.html">взгляните на его выполнение</a>).</p>
+</div>
+
+<p>Значение атрибута —  это буквально код JavaScript, который вы хотите запустить при возникновении события. В приведенном выше примере вызывается функция, определенная внутри элемента {{htmlelement ("script")}} на той же странице, но вы также можете вставить JavaScript непосредственно внутри атрибута, например:</p>
+
+<pre class="brush: html notranslate">&lt;button onclick="alert('Hello, this is my old-fashioned event handler!');"&gt;Press me&lt;/button&gt;</pre>
+
+<p>Для многих свойств обработчика событий существуют эквиваленты в виде атрибутов HTML. Однако, не рекомендуется их использовать — это считается плохой практикой. Использование атрибутов для регистрации обработчика событий кажется простым и быстрым методом, но такое описание обработчиков также скоро становится неудобным и неэффективным.</p>
+
+<p>Более того, не рекомендуется смешивать HTML и JavaScript файлы, так как в дальнейшем такой код становится сложнее с точки зрения обработки (парсинга). Лучше держать весь JavaScript в одном месте. Также, если он находится в отдельном файле, вы можете применить его к нескольким документам HTML.</p>
+
+<p>Даже при работе только в одном файле использование встроенных обработчиков не является хорошей идеей. Ладно, если у Вас одна кнопка, но что, если у вас их 100? Вам нужно добавить в файл 100 атрибутов; обслуживание такого кода очень быстро превратится в кошмар. С помощью JavaScript вы можете легко добавить функцию обработчика событий ко всем кнопкам на странице независимо от того, сколько их было.</p>
+
+<p>Например:</p>
+
+<pre class="brush: js notranslate">const buttons = document.querySelectorAll('button');
+
+for (var i = 0; i &lt; buttons.length; i++) {
+ buttons[i].onclick = bgChange;
+}</pre>
+
+<p class="brush: js">Обратите внимание, что для перебора всех элементов, которые содержит объект <code><a href="/en-US/docs/Web/API/NodeList">NodeList</a></code>, можно воспользоваться встроенным методом <code><a href="/en-US/docs/Web/API/NodeList/forEach">forEach()</a></code>:</p>
+
+<pre class="brush: js notranslate">buttons.forEach(function(button) {
+ button.onclick = bgChange;
+});</pre>
+
+<div class="note">
+<p><strong>Примечание</strong>: Разделение логики Вашей программы и Вашего контента также делает Ваш сайт более дружественным к поисковым системам.</p>
+</div>
+
+<h3 id="Функции_addEventListener_и_removeEventListener">Функции addEventListener() и removeEventListener()</h3>
+
+<p>Новый тип механизма событий определен в спецификации <a href="https://www.w3.org/TR/DOM-Level-2-Events/">Document Object Model (DOM) Level 2 Events</a>, которая предоставляет браузеру новую функцию — <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener">addEventListener()</a></code>. Работает она аналогично свойствам обработчика событий, но синтаксис совсем другой. Наш пример со случайным цветом мог бы выглядеть и так:</p>
+
+<pre class="brush: js notranslate">var btn = document.querySelector('button');
+
+function bgChange() {
+ var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
+ document.body.style.backgroundColor = rndCol;
+}
+
+btn.addEventListener('click', bgChange);</pre>
+
+<div class="note">
+<p><strong>Примечание</strong>: Вы можете найти <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/random-color-addeventlistener.html">исходный код</a> из этого примера на GitHub (также <a href="http://mdn.github.io/learning-area/javascript/building-blocks/events/random-color-addeventlistener.html">взгляните на его выполнение</a>).</p>
+</div>
+
+<p>Внутри функции <code>addEventListener()</code> мы указываем два параметра — имя события, для которого мы хотим зарегистрировать этот обработчик, и код, содержащий функцию обработчика, которую мы хотим запустить в ответ. Обратите внимание, что будет целесообразно поместить весь код внутри функции <code>addEventListener()</code> в анонимную функцию, например:</p>
+
+<pre class="brush: js notranslate">btn.addEventListener('click', function() {
+ var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
+ document.body.style.backgroundColor = rndCol;
+});</pre>
+
+<p>Этот механизм имеет некоторые преимущества по сравнению с более старыми механизмами, рассмотренными ранее. Например, существует аналогичная функция <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener">removeEventListener()</a></code>, которая удаляет ранее добавленный прослушиватель. Это приведет к удалению набора слушателей в первом блоке кода в этом разделе:</p>
+
+<pre class="brush: js notranslate">btn.removeEventListener('click', bgChange);</pre>
+
+<p>Это не важно для простых небольших программ, но для более крупных и более сложных программ он может повысить эффективность очистки старых неиспользуемых обработчиков событий. Кроме того, это позволяет вам иметь одну и ту же кнопку, выполняющую различные действия в разных обстоятельствах — все, что вам нужно сделать, это добавить/удалить обработчики событий, если это необходимо.</p>
+
+<p>Также, вы можете зарегистрировать несколько обработчиков для одного и того же прослушивателя. Следующие два обработчика не будут применяться:</p>
+
+<pre class="brush: js notranslate">myElement.onclick = functionA;
+myElement.onclick = functionB;</pre>
+
+<p>Поскольку вторая строка будет перезаписывать значение <code>onclick</code>, установленное первой. Однако, если:</p>
+
+<pre class="brush: js notranslate">myElement.addEventListener('click', functionA);
+myElement.addEventListener('click', functionB);</pre>
+
+<p>Обе функции будут выполняться при щелчке элемента.</p>
+
+<p>Кроме того, в этом механизме событий имеется ряд других мощных функций и опций. Эта тема выходит за рамки данной статьи, но если вы хотите изучить подробнее, переходите по ссылкам: <a href="/ru/docs/Web/API/EventTarget/addEventListener">Метод Event​Target​.add​Event​Listener()</a> и <a href="/ru/docs/Web/API/EventTarget/removeEventListener">Метод Event​Target​.remove​Event​Listener()</a>.</p>
+
+<h3 id="Какой_механизм_мне_использовать">Какой механизм мне использовать?</h3>
+
+<p>Из трех механизмов определенно не нужно использовать атрибуты событий HTML. Как упоминалось выше, это устаревшая и плохая практика.</p>
+
+<p>Остальные два являются относительно взаимозаменяемыми, по крайней мере для простых целей</p>
+
+<ul>
+ <li>Свойства обработчика событий имеют меньшую мощность и параметры, но лучше совместимость между браузерами (поддерживается еще в Internet Explorer 8). Вероятно, вам следует начать с них, когда вы учитесь.</li>
+ <li>События уровня 2 DOM (<code>addEventListener()</code> и т. д.) являются более мощными, но также могут стать более сложными и хуже поддерживаться (поддерживается еще в Internet Explorer 9). Вам также стоит поэкспериментировать с ними и стремиться использовать их там, где это возможно.</li>
+</ul>
+
+<p>Основные преимущества третьего механизма заключаются в том, что при необходимости можно удалить код обработчика событий, используя <code>removeEventListener()</code>, и так же можно добавить несколько элементов-слушателей того же типа к элементам. Например, вы можете вызвать <code>addEventListener('click', function() {...})</code> для элемента несколько раз, с разными функциями, указанными во втором аргументе. Это невозможно при использовании свойств обработчика событий, поскольку любые последующие попытки установить свойство будут перезаписывать более ранние, например:</p>
+
+<pre class="brush: js notranslate">element.onclick = function1;
+element.onclick = function2;
+etc.</pre>
+
+<div class="note">
+<p><strong>Примечание:</strong> Если вам требуется поддержка браузеров старше Internet Explorer 8 в вашем проекте, вы можете столкнуться с трудностями, так как такие старые браузеры используют старые модели событий из более новых браузеров. Но не бойтесь, большинство библиотек JavaScript (например, <code>jQuery</code>) имеют встроенные функции, которые абстрагируют различия между браузерами. Не беспокойтесь об этом слишком много на этапе вашего учебного путешествия.</p>
+</div>
+
+<h2 id="Другие_концепции_событий">Другие концепции событий</h2>
+
+<p>Рассмотрим некоторые современные концепции, имеющие отношение к событиям. На данный момент не обязательно понимать их полностью, но предстывление о них поможет лучше понять некоторые модели кода, с которыми вы, вероятно, столкнетесь.</p>
+
+<h3 id="Объекты_событий">   Объекты событий</h3>
+
+<p>Иногда внутри функции обработчика событий вы можете увидеть параметр, заданный с таким именем, как <code>event</code>, <code>evt</code> или просто <code>e</code>. Называется он <strong>объектом события</strong> и он автоматически передается обработчикам событий для предоставления дополнительных функций и информации. Например, давайте немного перепишем наш прмер со случайным цветом:</p>
+
+<pre class="brush: js notranslate">function bgChange(e) {
+ var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
+ e.target.style.backgroundColor = rndCol;
+ console.log(e);
+}
+
+btn.addEventListener('click', bgChange);</pre>
+
+<div class="note">
+<p><strong>Примечание</strong>: Вы можете найти <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/random-color-eventobject.html">исходник кода</a> для этого примера на GitHub (также <a href="http://mdn.github.io/learning-area/javascript/building-blocks/events/random-color-eventobject.html">взгляните на его выполнение</a>).</p>
+</div>
+
+<p>Итак в коде выше мы включаем объект события <strong><code>e</code></strong> в функцию, а в функции — настройку стиля фона для <code>e.target</code>, который является кнопкой. Свойство объекта события <code>target</code> всегда является ссылкой на элемент, с которым только что произошло событие. Поэтому в этом примере мы устанавливаем случайный цвет фона на кнопке, а не на странице.</p>
+
+<div class="note">
+<p><strong>Примечание:</strong> Вместо <code>e</code>/<code>evt</code>/<code>event</code> можно использовать любое имя для объекта события, которое затем можно использовать для ссылки на него в функции обработчика событий. <code>e</code>/<code>evt</code>/<code>event</code> чаще всего используются разработчиками, потому что они короткие и легко запоминаются. И хорошо придерживаться стандарта.</p>
+</div>
+
+<p><code>e.target</code> применяют, когда нужно установить один и тот же обработчик событий на несколько элементов и, когда на них происходит событие, применить определенное действие к ним ко всем. Например, у вас может быть набор из 16 плиток, которые исчезают при нажатии. Полезно всегда иметь возможность просто указать, чтобы объект исчез, как <code>e.target</code>, вместо того, чтобы выбирать его более сложным способом. В следующем примере (см. исходный код на  <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/useful-eventtarget.html">useful-eventtarget.html</a>,а как он работает можно посмотреть <a href="https://mdn.github.io/learning-area/javascript/building-blocks/events/useful-eventtarget.html">здесь</a>), мы создаем 16 элементов {{htmlelement ("div")}} с использованием JavaScript. Затем мы выберем все из них, используя {{domxref ("document.querySelectorAll()")}}, и с помощью цикла <code>for</code> выберем каждый из них, добавив обработчик <code>onclick</code> к каждому так, чтобы случайный цвет применялся к каждому клику:</p>
+
+<pre class="brush: js notranslate">var divs = document.querySelectorAll('div');
+
+for (var i = 0; i &lt; divs.length; i++) {
+ divs[i].onclick = function(e) {
+ e.target.style.backgroundColor = bgChange();
+ }
+}</pre>
+
+<p>Результат выглядит следующим образом (попробуйте щелкнуть по нему):</p>
+
+<div class="hidden">
+<h6 id="Hidden_example">Hidden example</h6>
+
+<pre class="brush: html notranslate">&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+ &lt;head&gt;
+ &lt;meta charset="utf-8"&gt;
+ &lt;title&gt;Useful event target example&lt;/title&gt;
+ &lt;style&gt;
+ div {
+ background-color: #ff6600;
+ height: 100px;
+ width: 25%;
+ float: left;
+ }
+ &lt;/style&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+ &lt;script&gt;
+ for (var i = 1; i &lt;= 16; i++) {
+ var myDiv = document.createElement('div');
+ document.body.appendChild(myDiv);
+ }
+
+ function random(number) {
+ return Math.floor(Math.random()*number);
+ }
+
+ function bgChange() {
+ var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
+ return rndCol;
+ }
+
+ var divs = document.querySelectorAll('div');
+
+ for (var i = 0; i &lt; divs.length; i++) {
+ divs[i].onclick = function(e) {
+ e.target.style.backgroundColor = bgChange();
+ }
+ }
+ &lt;/script&gt;
+ &lt;/body&gt;
+&lt;/html&gt;</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Hidden_example', '100%', 400) }}</p>
+
+<p>Большинство обработчиков событий, с которыми вы столкнулись, имеют только стандартный набор свойств и функций (методов), доступных для объекта события (см. {{domxref("Event")}} для ссылки на полный список). Однако некоторые более продвинутые обработчики добавляют специальные свойства, содержащие дополнительные данные, которые им необходимо выполнять. Например, <a href="https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder_API">Media Recorder API</a> имеет событие, доступное для данных, которое срабатывает, когда записано какое-либо аудио или видео и доступно для выполнения чего-либо (например, для сохранения или воспроизведения). Соответствующий объект события <a href="https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder/ondataavailable">ondataavailable</a> handler имеет свойство данных, содержащее записанные аудио- или видеоданные, чтобы вы могли получить к нему доступ и что-то сделать с ним.</p>
+
+<h3 id="Предотвращение_поведения_по_умолчанию">    Предотвращение поведения по умолчанию</h3>
+
+<p>Иногда бывают ситуации, когда нужно остановить событие, выполняющее то, что оно делает по умолчанию. Наиболее распространенным примером является веб-форма, например, пользовательская форма регистрации. Когда вы вводите данные и нажимаете кнопку отправки, естественное поведение заключается в том, что данные должны быть отправлены на указанную страницу на сервере для обработки, а браузер перенаправлется на страницу с сообщением об успехе (или остаться на той же странице, если другое не указано).</p>
+
+<p>Но если пользователь отправил данные не правильно, как разработчик, вы хотите остановить отправку на сервер и выдать сообщение об ошибке с информацией о том, что не так и что нужно сделать. Некоторые браузеры поддерживают функции автоматической проверки данных формы, но, поскольку многие этого не делают, вам не следует полагаться на них и выполнять свои собственные проверки валидации. Давайте посмотрим на простой пример.</p>
+
+<p>Простая форма HTML, в которой требуется ввести ваше имя и фамилию:</p>
+
+<pre class="brush: html notranslate">&lt;form&gt;
+ &lt;div&gt;
+ &lt;label for="fname"&gt;Имя: &lt;/label&gt;
+ &lt;input id="fname" type="text"&gt;
+ &lt;/div&gt;
+ &lt;div&gt;
+ &lt;label for="lname"&gt;Фамилия: &lt;/label&gt;
+ &lt;input id="lname" type="text"&gt;
+ &lt;/div&gt;
+ &lt;div&gt;
+ &lt;input id="submit" type="submit"&gt;
+ &lt;/div&gt;
+&lt;/form&gt;
+&lt;p&gt;&lt;/p&gt;</pre>
+
+<div class="hidden">
+<pre class="brush: css notranslate">div {
+ margin-bottom: 10px;
+}
+</pre>
+</div>
+
+<p>В JavaScript мы реализуем очень простую проверку внутри обработчика события <a href="https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onsubmit">onsubmit</a> (событие "отправить" запускается в форме, когда оно отправлено), который проверяет, пусты ли текстовые поля. Если они пусты, мы вызываем функцию <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault">preventDefault()</a></code> объекта события, которая останавливает отправку формы, а затем выводит сообщение об ошибке в абзаце ниже нашей формы, чтобы сообщить пользователю, что не так:</p>
+
+<pre class="brush: js notranslate">var form = document.querySelector('form');
+var fname = document.getElementById('fname');
+var lname = document.getElementById('lname');
+var submit = document.getElementById('submit');
+var para = document.querySelector('p');
+
+form.onsubmit = function(e) {
+ if (fname.value === '' || lname.value === '') {
+ e.preventDefault();
+ para.textContent = 'Оба поля должны быть заполнены!';
+ }
+}</pre>
+
+<p>Очевидно, что это довольно слабая проверка формы - это не помешает пользователю отправить форму с пробелами или цифрами, введенными в поля, но для примера подходит. Вывод выглядит следующим образом:</p>
+
+<p>{{ EmbedLiveSample('Предотвращение_поведения_по_умолчанию', '100%', 140) }}</p>
+
+<div class="note">
+<p><strong>Примечание</strong>: чтобы увидеть исходный код, откройте <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/preventdefault-validation.html">preventdefault-validation.html</a> (также <a href="http://mdn.github.io/learning-area/javascript/building-blocks/events/preventdefault-validation.html">запустите</a> здесь).</p>
+</div>
+
+<h3 id="Всплытие_и_перехват_событий">Всплытие и перехват событий</h3>
+
+<p>Последним предметом для рассмотрения в этой теме является то, с чем вы не часто будете сталкиваться, но это может стать настоящей головной болью, если вы не поймете, как работает следующий механизм. <em>Всплытие</em> и <em>перехват событий</em> — два механизма, описывающих, что происходит, когда два обработчика одного и того же события активируются на одном элементе. Посмотрим на пример. Чтобы сделать это проще — откройте пример <a href="http://mdn.github.io/learning-area/javascript/building-blocks/events/show-video-box.html">show-video-box.html</a> в одной вкладке и <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/show-video-box.html">исходный код </a>в другой вкладке. Он также представлен ниже:</p>
+
+<div class="hidden">
+<h6 id="Hidden_video_example">Hidden video example</h6>
+
+<pre class="brush: html notranslate">&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+ &lt;head&gt;
+ &lt;meta charset="utf-8"&gt;
+ &lt;title&gt;Show video box example&lt;/title&gt;
+ &lt;style&gt;
+ div {
+ position: absolute;
+ top: 50%;
+ transform: translate(-50%,-50%);
+ width: 550px;
+ height: 420px;
+ border-radius: 10px;
+ background-color: #eee;
+ background-image: linear-gradient(to bottom, rgba(0,0,0,0.1), rgba(0,0,0,0.4));
+ }
+
+ .hidden {
+ left: -50%;
+ }
+
+ .showing {
+ left: 50%;
+ }
+
+ div video {
+ display: block;
+ width: 400px;
+ margin: 50px auto;
+ }
+
+ &lt;/style&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+ &lt;button&gt;Display video&lt;/button&gt;
+
+ &lt;div class="hidden"&gt;
+ &lt;video&gt;
+ &lt;source src="https://raw.githubusercontent.com/mdn/learning-area/master/javascript/building-blocks/events/rabbit320.mp4" type="video/mp4"&gt;
+ &lt;source src="https://raw.githubusercontent.com/mdn/learning-area/master/javascript/building-blocks/events/rabbit320.webm" type="video/webm"&gt;
+ &lt;p&gt;Your browser doesn't support HTML5 video. Here is a &lt;a href="rabbit320.mp4"&gt;link to the video&lt;/a&gt; instead.&lt;/p&gt;
+ &lt;/video&gt;
+ &lt;/div&gt;
+
+ &lt;script&gt;
+
+ var btn = document.querySelector('button');
+ var videoBox = document.querySelector('div');
+ var video = document.querySelector('video');
+
+ btn.onclick = function() {
+ displayVideo();
+ }
+
+ function displayVideo() {
+ if(videoBox.getAttribute('class') === 'hidden') {
+ videoBox.setAttribute('class','showing');
+ }
+ }
+
+ videoBox.addEventListener('click',function() {
+ videoBox.setAttribute('class','hidden');
+ });
+
+ video.addEventListener('click',function() {
+ video.play();
+ });
+
+ &lt;/script&gt;
+ &lt;/body&gt;
+&lt;/html&gt;</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Hidden_video_example', '100%', 500) }}</p>
+
+<p>Это довольно простой пример, который показывает и скрывает {{htmlelement ("div")}} с элементом {{htmlelement ("video")}} внутри него:</p>
+
+<pre class="brush: html notranslate">&lt;button&gt;Display video&lt;/button&gt;
+
+&lt;div class="hidden"&gt;
+ &lt;video&gt;
+ &lt;source src="rabbit320.mp4" type="video/mp4"&gt;
+ &lt;source src="rabbit320.webm" type="video/webm"&gt;
+ &lt;p&gt;Your browser doesn't support HTML5 video. Here is a &lt;a href="rabbit320.mp4"&gt;link to the video&lt;/a&gt; instead.&lt;/p&gt;
+ &lt;/video&gt;
+&lt;/div&gt;</pre>
+
+<p>При нажатии на кнопку {{htmlelement ("button")}}, изменяется атрибут класса элемента <code>&lt;div&gt;</code> с <code>hidden</code> на <code>showing</code> (CSS примера содержит эти два класса, которые размещают блок вне экрана и на экране соответственно):</p>
+
+<pre class="brush: css notranslate">div {
+        position: absolute;
+        top: 50%;
+        transform: translate(-50%,-50%);
+        ...
+      }
+<font color="#6f42c1" face="SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace">.hidden {
+  left: -50%;
+  }
+.showing {
+  left: 50%;
+  }</font></pre>
+
+<pre class="brush: js notranslate">var btn = document.querySelector('button');
+btn.onclick = function() {
+ videoBox.setAttribute('class', 'showing');
+}</pre>
+
+<p>Затем мы добавляем еще пару обработчиков событий <code>onclick.</code> Первый к <code>&lt;div&gt;</code>, а второй к <code>&lt;video&gt;</code>. Идея заключается в том, чтобы при щелчке по области <code>&lt;div&gt;</code> вне зоны видео поле снова скрылось, а при клике в области <code>&lt;video&gt;</code>  видео начало воспроизводиться.</p>
+
+<pre class="brush: js notranslate">var videoBox = document.querySelector('div');
+var video = document.querySelector('video');
+
+videoBox.onclick = function() {
+ videoBox.setAttribute('class', 'hidden');
+};
+
+video.onclick = function() {
+ video.play();
+};</pre>
+
+<p>Но есть проблема: когда вы нажимаете на видео, оно начинает воспроизводиться, но одновременно вызывает скрытие <code>&lt;div&gt;</code>. Это связано с тем, что видео находится внутри <code>&lt;div&gt;,</code> это часть его, поэтому нажатие на видео фактически запускает оба вышеуказанных обработчика событий.</p>
+
+<h4 id="Всплытие_и_перехват_событий_—_концепция_выполнения"><strong>Всплытие и перехват событий — концепция выполнения</strong></h4>
+
+<p>Когда событие инициируется элементом, который имеет родительские элементы (например, {{htmlelement ("video")}} в нашем случае), современные браузеры выполняют две разные фазы —  фазу  <strong>захвата</strong> и фазу <strong>всплытия</strong>.</p>
+
+<p>На стадии <strong>захвата </strong>происходит следующее:</p>
+
+<ul>
+ <li>Браузер проверяет, имеет ли самый внешний элемент ({{htmlelement ("html")}}) обработчик события <code>onclick</code>, зарегистрированный на нем на этапе захвата и запускает его, если это так.</li>
+ <li>Затем он переходит к следующему элементу внутри <code>&lt;html&gt;</code> и выполняет то же самое, затем следующее и так далее, пока не достигнет элемента, на который на самом деле нажали.</li>
+</ul>
+
+<p>На стадии <strong>всплытия</strong> происходит полная противоположность:</p>
+
+<ul>
+ <li>Браузер проверяет, имеет ли элемент, который был фактически нажат, обработчик события <code>onclick</code>, зарегистрированный на нем в фазе высплытия, и запускает его, если это так.</li>
+ <li>Затем он переходит к следующему непосредственному родительскому элементу и выполняет то же самое, затем следующее и так далее, пока не достигнет элемента <code>&lt;html&gt;</code>.</li>
+</ul>
+
+<p><a href="https://mdn.mozillademos.org/files/14075/bubbling-capturing.png"><img alt="" src="https://mdn.mozillademos.org/files/14075/bubbling-capturing.png" style="display: block; height: 452px; margin: 0px auto; width: 960px;"></a></p>
+
+<p>(Нажмите на изображение, чтобы увеличить диаграмму)</p>
+
+<p>В современных браузерах по умолчанию все обработчики событий регистрируются в фазе <strong><em>всплытия</em></strong>. Итак, в нашем текущем примере, когда вы нажимаете видео, событие click вызывается из элемента <code>&lt;video&gt;</code> наружу, в элемент <code>&lt;html&gt;</code>. По пути:</p>
+
+<ul>
+ <li>Он находит обработчик <code>video.onclick...</code> и запускает его, поэтому видео сначала начинает воспроизводиться.</li>
+ <li>Затем он находит обработчик <code>videoBox.onclick...</code> и запускает его, поэтому видео также скрывается.</li>
+</ul>
+
+<h4 id="Исправление_проблемы_с_помощью_stopPropagation">Исправление проблемы с помощью stopPropagation()</h4>
+
+<p>Чтобы исправить это раздражающее поведение, стандартный объект события имеет функцию, называемую <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation">stopPropagation()</a></code>, которая при вызове в обработчике событий объекта делает так, чтобы обработчик выполнялся, но событие не всплывало дальше по цепочке, поэтому не будут запускаться другие обработчики.</p>
+
+<p>Поэтому мы можем исправить нашу текущую проблему, изменив вторую функцию-обработчик в предыдущем блоке кода:</p>
+
+<pre class="brush: js notranslate">video.onclick = function(e) {
+ e.stopPropagation();
+ video.play();
+};</pre>
+
+<p>Вы можете попробовать создать локальную копию <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/show-video-box.html">show-video-box.html</a> и попробовать его самостоятельно исправить или просмотреть исправленный результат в <a href="http://mdn.github.io/learning-area/javascript/building-blocks/events/show-video-box-fixed.html">show-video-box-fixed.html</a> (также см. <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/show-video-box-fixed.html">исходный код здесь</a>).</p>
+
+<div class="note"><strong>Примечание</strong>: Зачем беспокоиться как с захватом, так и с всплыванием? Что ж, в старые добрые времена, когда браузеры были менее совместимы, чем сейчас, Netscape использовал только захват событий, а Internet Explorer использовал только всплывающие события. Когда W3C решил попытаться стандартизировать поведение и достичь консенсуса, они в итоге получили эту систему, которая включала в себя и то, и другое, что реализовано в одном из современных браузеров.</div>
+
+<div class="note">
+<p><strong>Примечание</strong>: Как упоминалось выше, по умолчанию все обработчики событий регистрируются в фазе всплытия и это имеет смысл в большинстве случаев. Если вы действительно хотите зарегистрировать событие в фазе захвата, вы можете сделать это, зарегистрировав обработчик с помощью <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener">addEventListener()</a></code> и установив для третьего дополнительного свойства значение <code>true</code>.</p>
+</div>
+
+<h4 id="Делегирование_события"><strong>Делегирование</strong> события</h4>
+
+<p>Всплытие также позволяет нам использовать <strong>делегирование событий. </strong> Если у какого-либо родительского элемента есть множество дочерних элементов, и вы хотите, чтобы определенный код выполнялся при щелчке (событии) на каждом из дочерних элементов, можно установить прослушиватель событий на родительском элементе и события, происходящие на дочерних элементах будут всплывать до их родителя. При этом не нужно устанавливать прослушивателя событий на каждом дочернем элементе.</p>
+
+<p>Хорошим примером является серия элементов списка. Если вы хотите, чтобы каждый из них, например, отображал сообщение при нажатии, вы можете установить прослушиватель событий <code>click</code> для родительского элемента <code>&lt;ul&gt;</code> и он будет всплывать в элементах списка.</p>
+
+<p>Эту концепцию объясняет в своем блоге Дэвид Уолш, где приводит несколько примеров. (см. <a href="https://davidwalsh.name/event-delegate">How JavaScript Event Delegation Works</a>.)</p>
+
+<h2 id="Вывод">Вывод</h2>
+
+<p>Это все, что вам нужно знать о веб-событиях на этом этапе. Как уже упоминалось, события не являются частью основного JavaScript — они определены в веб-интерфейсах браузера (<a href="/ru/docs/Web/API">Web API</a>).</p>
+
+<p>Кроме того, важно понимать, что различные контексты, в которых используется JavaScript, обычно имеют разные модели событий — от веб-API до других областей, таких как браузерные WebExtensions и Node.js (серверный JavaScript). Может сейчас вы не особо в этом разбираетесь, но по мере изучения веб-разработки начнет приходить более ясное понимание тематики.</p>
+
+<p>Если у вас возникли вопросы, попробуйте прочесть статью снова или <a href="https://developer.mozilla.org/en-US/docs/Learn#Contact_us">обратитесь за помощью к нам</a>.</p>
+
+<h2 id="См._также">См. также</h2>
+
+<ul>
+ <li><a href="http://www.quirksmode.org/js/events_order.html">Event order</a> (обсуждение захвата и всплытий) — превосходно детализированная часть от Peter-Paul Koch.</li>
+ <li><a href="http://www.quirksmode.org/js/events_access.html">Event accessing</a> (discussing of the event object) — another excellently detailed piece by Peter-Paul Koch.</li>
+ <li><a href="/en-US/docs/Web/Events">Event reference</a></li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Return_values","Learn/JavaScript/Building_blocks/Image_gallery", "Learn/JavaScript/Building_blocks")}}</p>
+
+<h2 id="В_этом_модуле">В этом модуле</h2>
+
+<ul>
+ <li><a href="/ru/docs/Learn/JavaScript/Building_blocks/conditionals">Принятие решений в Вашем коде — условные конструкции</a></li>
+ <li><a href="/ru/docs/Learn/JavaScript/Building_blocks/Looping_code">Зацикливание кода</a></li>
+ <li><a href="/ru/docs/Learn/JavaScript/Building_blocks/Functions">Функции — Переиспользуемые блоки кода</a></li>
+ <li><a href="/ru/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">Создайте свою собственную функцию</a></li>
+ <li><a href="/ru/docs/Learn/JavaScript/Building_blocks/Return_values">Возвращаемое значение функции</a></li>
+ <li><a href="/ru/docs/Learn/JavaScript/Building_blocks/События">Введение в события</a></li>
+ <li><a href="/ru/docs/Learn/JavaScript/Building_blocks/Image_gallery">Создание галереи</a></li>
+</ul>
+
+<div class="s3gt_translate_tooltip_mini_box" id="s3gt_translate_tooltip_mini" style="background: initial !important; border: initial !important; border-radius: initial !important; border-collapse: initial !important; direction: ltr !important; font-weight: initial !important; height: initial !important; letter-spacing: initial !important; max-width: initial !important; min-height: initial !important; margin: auto !important; outline: initial !important; padding: initial !important; position: absolute; text-align: initial !important; text-shadow: initial !important; width: initial !important; display: initial !important; color: inherit !important; font-size: 13px !important; font-family: X-LocaleSpecific, sans-serif, Tahoma, Helvetica !important; line-height: 13px !important; vertical-align: top !important; white-space: inherit !important; left: 416px; top: 2989px; opacity: 0.35;">
+<div class="s3gt_translate_tooltip_mini" id="s3gt_translate_tooltip_mini_sound" style="width: 12px; height: 12px; border-radius: 4px;" title="Прослушать"></div>
+
+<div class="s3gt_translate_tooltip_mini" id="s3gt_translate_tooltip_mini_copy" style="width: 12px; height: 12px; border-radius: 4px;" title="Скопировать текст в буфер обмена"></div>
+</div>
diff --git a/files/ru/learn/javascript/client-side_web_apis/client-side_storage/index.html b/files/ru/learn/javascript/client-side_web_apis/client-side_storage/index.html
new file mode 100644
index 0000000000..114e7821a1
--- /dev/null
+++ b/files/ru/learn/javascript/client-side_web_apis/client-side_storage/index.html
@@ -0,0 +1,794 @@
+---
+title: Client-side storage
+slug: Learn/JavaScript/Client-side_web_APIs/Client-side_storage
+translation_of: Learn/JavaScript/Client-side_web_APIs/Client-side_storage
+---
+<p>{{LearnSidebar}}</p>
+
+<div>{{PreviousMenu("Learn/JavaScript/Client-side_web_APIs/Video_and_audio_APIs", "Learn/JavaScript/Client-side_web_APIs")}}</div>
+
+<div></div>
+
+<p class="summary">Современные веб-браузеры поддерживают несколько способов хранения данных из веб-сайтов на компьютере пользователя - с разрешения пользователя - чтобы потом получать их, когда это необходимо. Это позволяет долгосрочно хранить данные, сохранять сайты или документы для использования без подключения к сети, сохранять пользовательские настройки для вашего сайта и многое другое. В этой статье объясняются основы того, как это все работает.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Что нужно знать:</th>
+ <td>JavaScript basics (see <a href="/en-US/docs/Learn/JavaScript/First_steps">first steps</a>, <a href="/en-US/docs/Learn/JavaScript/Building_blocks">building blocks</a>, <a href="/en-US/docs/Learn/JavaScript/Objects">JavaScript objects</a>), the <a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Introduction">basics of Client-side APIs</a></td>
+ </tr>
+ <tr>
+ <th scope="row">Цель статьи:</th>
+ <td>To learn how to use client-side storage APIs to store application data.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Хранение_данных_на_стороне_клиента">Хранение данных на стороне клиента?</h2>
+
+<p>Ранее, мы говорили о разнице между <a href="/en-US/docs/Learn/Server-side/First_steps/Client-Server_overview#Static_sites">статическими</a> и <a href="/en-US/docs/Learn/Server-side/First_steps/Client-Server_overview#Dynamic_sites">динамическими сайтами</a>. Большинство современных веб-сайтов являются динамическими - они хранят данные на сервере, используя какую-то базу данных (серверное хранилище), а затем запускают код <a href="/en-US/docs/Learn/Server-side">на стороне сервера</a> чтобы извлечь необходимые данные, вставить их в шаблоны статических страниц и передать полученный HTML-код клиенту для отображения в браузере пользователя.</p>
+
+<p>Хранилище на стороне клиента работает по схожим принципам, но используется по-другому. Оно состоит из API-интерфейсов JavaScript, которые позволяют вам хранить данные на клиенте (то есть на компьютере пользователя), а затем извлекать их при необходимости. Это имеет много разных применений, таких как:</p>
+
+<ul>
+ <li>Персонализация настроек сайта (например, отображение выбранных пользователем виджетов, цветовой схемы или размера шрифта).</li>
+ <li>Сохранение предыдущей активности на сайте (например, сохранение содержимого корзины покупок из предыдущего сеанса, запоминание, был ли пользователь ранее авторизован в системе).</li>
+ <li>Сохранение данных и ресурсов локально, так что сайт будет быстрее (и, возможно, экономичнее) загружаться или использоваться без подключения к сети.</li>
+ <li>Сохранение созданных веб-приложением документов локально для использования в автономном режиме.</li>
+</ul>
+
+<p>Часто, хранилища на сторонах клиента и сервера используются совместно. К примеру, вы должны загрузить из базы данных пакет музыкальных файлов для веб-игры, или музыкальный плеер хранит их в базе данных на стороне клиента, и воспроизводит по мере необходимости.</p>
+
+<p>Пользователь должен будет загрузить музыкальные файлы только один раз - при последующих посещениях они будут извлечены из локальной базы данных.</p>
+
+<div class="note">
+<p><strong>Примечание.</strong> Существуют ограничения на объем данных, которые вы можете хранить с помощью API-интерфейсов на стороне клиента (возможно, как для отдельных API, так и в совокупности). Точный лимит варьируется в зависимости от браузера и, возможно, в зависимости от пользовательских настроек. Смотри <a href="/en-US/docs/Web/API/IndexedDB_API/Browser_storage_limits_and_eviction_criteria">Ограничения хранилища браузера и критерии переполнения</a> для большей информации.</p>
+</div>
+
+<h3 id="Старый_подход_куки">Старый подход: куки</h3>
+
+<p>Концепция хранения на стороне клиента существует уже давно. С первых дней Интернета, использовали <a href="/en-US/docs/Web/HTTP/Cookies">cookies</a> для хранения информации, чтобы персонализировать пользовательский опыт на веб-сайтах. Это самая ранняя форма хранилища на стороне клиента, обычно используемая в Интернете.</p>
+
+<p>Из-за этого возраста существует ряд проблем - как технических, так и с точки зрения пользовательского опыта - связанных с файлами cookie. Эти проблемы настолько значительны, что при первом посещении сайта людям, живущим в Европе, показываются сообщения, информирующие их о том, будут ли они использовать файлы cookie для хранения данных о них. Это связано с частью законодательства Европейского Союза, известного как  <a href="/en-US/docs/Web/HTTP/Cookies#EU_cookie_directive">EU Cookie directive</a>.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/15734/cookies-notice.png" style="display: block; margin: 0 auto;"></p>
+
+<p>По этим причинам мы не будем учить вас, как использовать куки в этой статье. Они устарели, у них множество <a href="/en-US/docs/Web/HTTP/Cookies#Security">проблем с безопастностью</a>, и неспособны хранить сложные данные. При этом существуют лучшие, более современные, способы хранения более широкого спектра данных на компьютере пользователя.</p>
+
+<p>Единственным преимуществом файлов cookie является то, что они поддерживаются очень старыми браузерами, поэтому, если ваш проект требует, чтобы вы поддерживали устаревшие браузеры (например, Internet Explorer 8 или более ранние версии), файлы cookie могут по-прежнему быть полезными, но для большинства проектов вы не нужно больше прибегать к ним.</p>
+
+<div class="note">
+<p>Почему по-прежнему создаются новые сайты с использованием файлов cookie? Это происходит главным образом из-за привычек разработчиков, использования старых библиотек, которые всё ещё используют куки-файлы, и наличия множества веб-сайтов, предоставляющих устаревшие справочные и учебные материалы для обучения хранению данных.</p>
+</div>
+
+<h3 id="Новый_подход_Web_Storage_и_IndexedDB">Новый подход: Web Storage и IndexedDB</h3>
+
+<p>Современные браузеры имеют гораздо более простые и эффективные API для хранения данных на стороне клиента, чем при использовании файлов cookie.</p>
+
+<ul>
+ <li>The <a href="/en-US/docs/Web/API/Web_Storage_API">Web Storage API</a> обеспечивает очень простой синтаксис для хранения и извлечения данных, состоящих из пар 'ключ' : 'значение'. Это полезно, когда вам просто нужно сохранить некоторые простые данные, такие как имя пользователя, вошли ли они в систему, какой цвет использовать для фона экрана и т. д.</li>
+ <li>The <a href="/en-US/docs/Web/API/IndexedDB_API">IndexedDB API</a> обеспечивает браузер полной базой данных для хранения сложных данных. Это может быть использовано для хранения полных наборов записей клиентов и даже до сложных типов данных, таких как аудио или видео файлы.</li>
+</ul>
+
+<p>Вы узнаете больше об этих API ниже.</p>
+
+<h3 id="Что_нас_ждёт_в_будущем_Cache_API">Что нас ждёт в будущем: Cache API</h3>
+
+<p>Некоторые современные браузеры поддерживают новое {{domxref("Cache")}} API. Этот API предназначен для хранения HTTP-ответов на конкретные запросы и очень полезен для таких вещей, как хранение ресурсов сайта в автономном режиме, чтобы впоследствии сайт можно было использовать без сетевого подключения. Cache обычно используется в сочетании с <a href="/en-US/docs/Web/API/Service_Worker_API">Service Worker API</a>, однако это не обязательно.</p>
+
+<p>Использование Cache и Service Workers - сложная тема, и мы не будем подробно останавливаться на ней в этой статье, хотя приведем простой пример {{anch("Offline asset storage")}} в разделе ниже.</p>
+
+<h2 id="Хранение_простых_данных_—_web_storage">Хранение простых данных — web storage</h2>
+
+<p><a href="/en-US/docs/Web/API/Web_Storage_API">Web Storage API</a> очень легко использовать — вы храните простые пары данных имя/значение (только строки, цифры и т.п.) и получаете их, когда необходимо.</p>
+
+<h3 id="Базовый_синтаксис">Базовый синтаксис</h3>
+
+<p>Посмотрите:</p>
+
+<ol>
+ <li>
+ <p>Во-первых, посмотрите наши <a href="https://mdn.github.io/learning-area/javascript/apis/client-side-storage/web-storage/index.html">web storage шаблоны</a> на GitHub (откройте в новой вкладке).</p>
+ </li>
+ <li>
+ <p>Откройте консоль инструментов JavaScript разработчика вашего браузера.</p>
+ </li>
+ <li>
+ <p>Все данные вашего веб-хранилища содержатся в двух объектоподобных структурах внутри браузера: {{domxref("Window.sessionStorage", "sessionStorage")}} и {{domxref("Window.localStorage", "localStorage")}}. Первый сохраняет данные до тех пор, пока браузер открыт (данные теряются при закрытии браузера), а второй сохраняет данные даже после того, как браузер закрыт, а затем снова открыт. Мы будем использовать второй в этой статье, так как он, как правило, более полезен.</p>
+
+ <p>{{domxref("Storage.setItem()")}} метод позволяет сохранить элемент данных в хранилище - он принимает два параметра: имя элемента и его значение. Попробуйте ввести это в свою консоль JavaScript (измените значение на свое собственное имя, если хотите!):</p>
+
+ <pre class="brush: js notranslate">localStorage.setItem('name','Chris');</pre>
+ </li>
+ <li>
+ <p>{{domxref("Storage.getItem()")}} метод принимает один параметр - имя элемента данных, который вы хотите получить - и возвращает значение элемента. Теперь введите эти строки в вашу консоль JavaScript:</p>
+
+ <pre class="brush: js notranslate">var myName = localStorage.getItem('name');
+myName</pre>
+
+ <p>После ввода во второй строке вы должны увидеть, что переменная <code>myName</code> теперь содержит значение элемента данных <code>name</code>.</p>
+ </li>
+ <li>
+ <p>{{domxref("Storage.removeItem()")}} метод принимает один параметр - имя элемента данных, который вы хотите удалить, - и удаляет этот элемент из веб-хранилища. Введите следующие строки в вашу консоль JavaScript:</p>
+
+ <pre class="brush: js notranslate">localStorage.removeItem('name');
+var myName = localStorage.getItem('name');
+myName</pre>
+
+ <p>Третья строка должна теперь возвращать ноль - элемент <code>name</code> больше не существует в веб-хранилище.</p>
+ </li>
+</ol>
+
+<h3 id="Данные_сохраняются!">Данные сохраняются!</h3>
+
+<p>Одной из ключевых особенностей веб-хранилища является то, что данные сохраняются между загрузками страниц (и даже в случае закрытия браузера, в случае <code>localStorage</code>). Давайте посмотрим на это в действии.</p>
+
+<ol>
+ <li>
+ <p>Снова откройте пустой шаблон нашего веб-хранилища, но на этот раз в другом браузере, отличном от того, в котором вы открыли этот учебник! Так будет удобнее.</p>
+ </li>
+ <li>
+ <p>Введите эти строки в консоль JavaScript браузера:</p>
+
+ <pre class="brush: js notranslate">localStorage.setItem('name','Chris');
+var myName = localStorage.getItem('name');
+myName</pre>
+
+ <p>Вы должны увидеть возвращенное имя элемента.</p>
+ </li>
+ <li>
+ <p>Теперь закройте браузер и откройте его снова.</p>
+ </li>
+ <li>
+ <p>Введите следующий код:</p>
+
+ <pre class="brush: js notranslate">var myName = localStorage.getItem('name');
+myName</pre>
+
+ <p>Вы должны увидеть, что значение всё ещё доступно, даже после закрытия / открытия браузера.</p>
+ </li>
+</ol>
+
+<h3 id="Для_каждого_домена_отдельное_хранилище">Для каждого домена отдельное хранилище</h3>
+
+<p>Существуют отдельные хранилища данных для каждого домена (каждый отдельный веб-адрес загружается в браузер). Вы увидите, что если вы загрузите два веб-сайта (например, google.com и amazon.com) и попытаетесь сохранить элемент на одном веб-сайте, он не будет доступен для другого веб-сайта.</p>
+
+<p>Это имеет смысл - вы можете представить себе проблемы безопасности, которые могут возникнуть, если веб-сайты смогут видеть данные друг друга!</p>
+
+<h3 id="Более_развернутый_пример">Более развернутый пример</h3>
+
+<p>Давайте применим эти новые знания, написав простой рабочий пример, чтобы дать вам представление о том, как можно использовать веб-хранилище. Наш пример позволит вам ввести имя, после чего страница обновится, чтобы дать вам персональное приветствие. Это состояние также будет сохраняться при перезагрузке страницы / браузера, поскольку имя хранится в веб-хранилище.</p>
+
+<p>Вы можете найти пример HTML на <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/web-storage/personal-greeting.html">personal-greeting.html</a> — он содержит простой веб-сайт с заголовком, контентом и нижним колонтитулом, а также форму для ввода вашего имени.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/15735/web-storage-demo.png" style="display: block; margin: 0 auto;"></p>
+
+<p>Давайте создадим пример, чтобы вы могли понять, как он работает.</p>
+
+<ol>
+ <li>
+ <p>Во-первых, сделайте локальную копию нашего  <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/web-storage/personal-greeting.html">personal-greeting.html</a> файла в новом каталоге на вашем компьютере.</p>
+ </li>
+ <li>
+ <p>Далее обратите внимание, как наш HTML ссылается на файл JavaScript с именем <code>index.js</code> (см. строку 40). Нам нужно создать его, и записать в него наш код JavaScript. Создайте файл <code>index.js</code> в том же каталоге, что и ваш HTML-файл.</p>
+ </li>
+ <li>
+ <p>Мы начнем с создания ссылок на все функции HTML, которыми мы должны манипулировать в этом примере - мы создадим их все как константы, поскольку эти ссылки не нужно изменять в жизненном цикле приложения. Добавьте следующие строки в ваш файл JavaScript:</p>
+
+ <pre class="brush: js notranslate">// create needed constants
+const rememberDiv = document.querySelector('.remember');
+const forgetDiv = document.querySelector('.forget');
+const form = document.querySelector('form');
+const nameInput = document.querySelector('#entername');
+const submitBtn = document.querySelector('#submitname');
+const forgetBtn = document.querySelector('#forgetname');
+
+const h1 = document.querySelector('h1');
+const personalGreeting = document.querySelector('.personal-greeting');</pre>
+ </li>
+ <li>
+ <p>Далее нам нужно включить небольшой прослушиватель событий, чтобы форма фактически не отправляла себя при нажатии кнопки отправки, так как это не то поведение, которое нам нужно. Добавьте этот фрагмент ниже вашего предыдущего кода:</p>
+
+ <pre class="brush: js notranslate">// Stop the form from submitting when a button is pressed
+form.addEventListener('submit', function(e) {
+ e.preventDefault();
+});</pre>
+ </li>
+ <li>
+ <p>Теперь нам нужно добавить прослушиватель событий, функция-обработчик которого будет запускаться при нажатии кнопки «Say hello». В комментариях подробно объясняется, что делает каждый бит, но в сущности здесь мы берем имя, которое пользователь ввел в поле ввода текста, и сохраняем его в веб-хранилище с помощью <code>setItem()</code>, затем запускаем функцию <code>nameDisplayCheck()</code>, которая будет обрабатывать обновление фактического текста сайта. Добавьте это в конец: </p>
+
+ <pre class="brush: js notranslate">// run function when the 'Say hello' button is clicked
+submitBtn.addEventListener('click', function() {
+ // store the entered name in web storage
+ localStorage.setItem('name', nameInput.value);
+ // run nameDisplayCheck() to sort out displaying the
+ // personalized greetings and updating the form display
+ nameDisplayCheck();
+});</pre>
+ </li>
+ <li>
+ <p>На этом этапе нам также необходим прослушиватель событий для запуска функции при нажатии кнопки «Forget» — она будет отображена только после того как кнопка «Say hello» будет нажата (две формы состояния для переключения между ними). В этой функции мы удаляем переменную <code>name</code> из веб-хранилища используя <code>removeItem()</code>, затем снова запускаем <code>nameDisplayCheck()</code> для обновления. Добавьте этот код в конец:</p>
+
+ <pre class="brush: js notranslate">// run function when the 'Forget' button is clicked
+forgetBtn.addEventListener('click', function() {
+ // Remove the stored name from web storage
+ localStorage.removeItem('name');
+ // run nameDisplayCheck() to sort out displaying the
+ // generic greeting again and updating the form display
+ nameDisplayCheck();
+});</pre>
+ </li>
+ <li>
+ <p>Самое время для определения самой функции <code>nameDisplayCheck()</code>. Здесь мы проверяем была ли переменная <code>name</code> сохранена в веб-хранилище с помощью <code>localStorage.getItem('name')</code> в качестве условия. Если переменная <code>name</code> была сохранена, то вызов вернёт - <code>true</code>; если же нет, то - <code>false</code>. Если <code>true</code>, мы показываем персональное приветствие, отображаем кнопку «Forget», и скрываем кнопку «Say hello». Если же <code>false</code>, мы отображаем общее приветствие и делаем обратное. Опять же, добавьте следующий код в конец:</p>
+
+ <pre class="brush: js notranslate">// define the nameDisplayCheck() function
+function nameDisplayCheck() {
+ // check whether the 'name' data item is stored in web Storage
+ if(localStorage.getItem('name')) {
+ // If it is, display personalized greeting
+ let name = localStorage.getItem('name');
+ h1.textContent = 'Welcome, ' + name;
+ personalGreeting.textContent = 'Welcome to our website, ' + name + '! We hope you have fun while you are here.';
+ // hide the 'remember' part of the form and show the 'forget' part
+ forgetDiv.style.display = 'block';
+ rememberDiv.style.display = 'none';
+ } else {
+ // if not, display generic greeting
+ h1.textContent = 'Welcome to our website ';
+ personalGreeting.textContent = 'Welcome to our website. We hope you have fun while you are here.';
+ // hide the 'forget' part of the form and show the 'remember' part
+ forgetDiv.style.display = 'none';
+ rememberDiv.style.display = 'block';
+ }
+}</pre>
+ </li>
+ <li>
+ <p>Последнее но не менее важное, нам необходимо запускать функцию <code>nameDisplayCheck()</code> при каждой загрузке страницы. Если мы не сделаем этого, персональное приветствие не будет сохранятся после перезагрузки страницы. Добавьте следующий фрагмент в конец вашего кода:</p>
+
+ <pre class="brush: js notranslate">document.body.onload = nameDisplayCheck;</pre>
+ </li>
+</ol>
+
+<p>Ваш пример закончен — отличная работа! Всё что теперь осталось это сохранить ваш код и протестировать вашу HTML страницу в браузере. Вы можете посмотреть нашу <a href="https://mdn.github.io/learning-area/javascript/apis/client-side-storage/web-storage/personal-greeting.html">завершённую версию работающую здесь</a>.</p>
+
+<div class="note">
+<p>Есть и другой, немного более комплексный пример описываемый в <a href="/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API">Using the Web Storage API</a>.</p>
+</div>
+
+<h2 id="Храним_более_сложную_информацию_в_IndexedDB">Храним более сложную информацию в IndexedDB</h2>
+
+<p><a href="/en-US/docs/Web/API/IndexedDB_API">IndexedDB API</a> (иногда сокращают до IDB) это полная база данных, доступная в браузере, в которой вы можете хранить сложные связанные данные, типы которых не ограничиваются простыми значениями, такими как строки или числа.</p>
+
+<p>Вы можете сохранить видео, фото, и почти все остальные файлы с IndexedDB. </p>
+
+<p dir="ltr" id="tw-target-text">Однако это обходится дорого: IndexedDB гораздо сложнее в использовании, чем Web Storage API.</p>
+
+<p dir="ltr" id="tw-target-text">В этом разделе мы действительно только коснемся того, на что он способен, но мы дадим вам достаточно, чтобы начать.</p>
+
+<h3 dir="ltr" id="Работа_с_примером_хранения_заметок">Работа с примером хранения заметок</h3>
+
+<p>Here we'll run you through an example that allows you to store notes in your browser and view and delete them whenever you like, getting you to build it up for yourself and explaining the most fundamental parts of IDB as we go along.</p>
+
+<p>The app looks something like this:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/15744/idb-demo.png" style="border-style: solid; border-width: 1px; display: block; margin: 0px auto;"></p>
+
+<p>Each note has a title and some body text, each individually editable. The JavaScript code we'll go through below has detailed comments to help you understand what's going on.</p>
+
+<h3 id="Предустановка">Предустановка</h3>
+
+<ol>
+ <li>First of all, make local copies of our <code><a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/notes/index.html">index.html</a></code>, <code><a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/notes/style.css">style.css</a></code>, and <code><a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/notes/index-start.js">index-start.js</a></code> files into a new directory on your local machine.</li>
+ <li>Have a look at the files. You'll see that the HTML is pretty simple: a web site with a header and footer, as well as a main content area that contains a place to display notes, and a form for entering new notes into the database. The CSS provides some simple styling to make it clearer what is going on. The JavaScript file contains five declared constants containing references to the {{htmlelement("ul")}} element the notes will be displayed in, the title and body {{htmlelement("input")}} elements, the {{htmlelement("form")}} itself, and the {{htmlelement("button")}}.</li>
+ <li>Rename your JavaScript file to <code>index.js</code>. You are now ready to start adding code to it.</li>
+</ol>
+
+<h3 id="Настраиваем_базу_данных">Настраиваем базу данных</h3>
+
+<p>Now let's look at what we have to do in the first place, to actually set up a database.</p>
+
+<ol>
+ <li>
+ <p>Below the constant declarations, add the following lines:</p>
+
+ <pre class="brush: js notranslate">// Create an instance of a db object for us to store the open database in
+let db;</pre>
+
+ <p>Here we are declaring a variable called <code>db</code> — this will later be used to store an object representing our database. We will use this in a few places, so we've declared it globally here to make things easier.</p>
+ </li>
+ <li>
+ <p>Next, add the following to the bottom of your code:</p>
+
+ <pre class="brush: js notranslate">window.onload = function() {
+
+};</pre>
+
+ <p>We will write all of our subsequent code inside this <code>window.onload</code> event handler function, called when the window's {{event("load")}} event fires, to make sure we don't try to use IndexedDB functionality before the app has completely finished loading (it could fail if we don't).</p>
+ </li>
+ <li>
+ <p>Inside the <code>window.onload</code> handler, add the following:</p>
+
+ <pre class="brush: js notranslate">// Open our database; it is created if it doesn't already exist
+// (see onupgradeneeded below)
+let request = window.indexedDB.open('notes', 1);</pre>
+
+ <p>This line creates a <code>request</code> to open version <code>1</code> of a database called <code>notes</code>. If this doesn't already exist, it will be created for you by subsequent code. You will see this request pattern used very often throughout IndexedDB. Database operations take time. You don't want to hang the browser while you wait for the results, so database operations are {{Glossary("asynchronous")}}, meaning that instead of happening immediately, they will happen at some point in the future, and you get notified when they're done.</p>
+
+ <p>To handle this in IndexedDB, you create a request object (which can be called anything you like — we called it <code>request</code> so it is obvious what it is for). You then use event handlers to run code when the request completes, fails, etc., which you'll see in use below.</p>
+
+ <div class="note">
+ <p><strong>Note</strong>: The version number is important. If you want to upgrade your database (for example, by changing the table structure), you have to run your code again with an increased version number, different schema specified inside the <code>onupgradeneeded</code> handler (see below), etc. We won't cover upgrading databases in this simple tutorial.</p>
+ </div>
+ </li>
+ <li>
+ <p>Now add the following event handlers just below your previous addition — again inside the <code>window.onload</code> handler:</p>
+
+ <pre class="brush: js notranslate">// onerror handler signifies that the database didn't open successfully
+request.onerror = function() {
+ console.log('Database failed to open');
+};
+
+// onsuccess handler signifies that the database opened successfully
+request.onsuccess = function() {
+ console.log('Database opened successfully');
+
+ // Store the opened database object in the db variable. This is used a lot below
+ db = request.result;
+
+ // Run the displayData() function to display the notes already in the IDB
+ displayData();
+};</pre>
+
+ <p>The {{domxref("IDBRequest.onerror", "request.onerror")}} handler will run if the system comes back saying that the request failed. This allows you to respond to this problem. In our simple example, we just print a message to the JavaScript console.</p>
+
+ <p>The {{domxref("IDBRequest.onsuccess", "request.onsuccess")}} handler on the other hand will run if the request returns successfully, meaning the database was successfully opened. If this is the case, an object representing the opened database becomes available in the {{domxref("IDBRequest.result", "request.result")}} property, allowing us to manipulate the database. We store this in the <code>db</code> variable we created earlier for later use. We also run a custom function called <code>displayData()</code>, which displays the data in the database inside the {{HTMLElement("ul")}}. We run it now so that the notes already in the database are displayed as soon as the page loads. You'll see this defined later on.</p>
+ </li>
+ <li>
+ <p>Finally for this section, we'll add probably the most important event handler for setting up the database: {{domxref("IDBOpenDBRequest.onupgradeneeded", "request.onupdateneeded")}}. This handler runs if the database has not already been set up, or if the database is opened with a bigger version number than the existing stored database (when performing an upgrade). Add the following code, below your previous handler:</p>
+
+ <pre class="brush: js notranslate">// Setup the database tables if this has not already been done
+request.onupgradeneeded = function(e) {
+ // Grab a reference to the opened database
+ let db = e.target.result;
+
+ // Create an objectStore to store our notes in (basically like a single table)
+ // including a auto-incrementing key
+ let objectStore = db.createObjectStore('notes', { keyPath: 'id', autoIncrement:true });
+
+ // Define what data items the objectStore will contain
+ objectStore.createIndex('title', 'title', { unique: false });
+ objectStore.createIndex('body', 'body', { unique: false });
+
+ console.log('Database setup complete');
+};</pre>
+
+ <p>This is where we define the schema (structure) of our database; that is, the set of columns (or fields) it contains. Here we first grab a reference to the existing database from <code>e.target.result</code> (the event target's <code>result</code> property), which is the <code>request</code> object. This is equivalent to the line <code>db = request.result;</code> inside the <code>onsuccess</code> handler, but we need to do this separately here because the <code>onupgradeneeded</code> handler (if needed) will run before the <code>onsuccess</code> handler, meaning that the <code>db</code> value wouldn't be available if we didn't do this.</p>
+
+ <p>We then use {{domxref("IDBDatabase.createObjectStore()")}} to create a new object store inside our opened database. This is equivalent to a single table in a conventional database system. We've given it the name notes, and also specified an <code>autoIncrement</code> key field called <code>id</code> — in each new record this will automatically be given an incremented value — the developer doesn't need to set this explicitly. Being the key, the <code>id</code> field will be used to uniquely identify records, such as when deleting or displaying a record.</p>
+
+ <p>We also create two other indexes (fields) using the {{domxref("IDBObjectStore.createIndex()")}} method: <code>title</code> (which will contain a title for each note), and <code>body</code> (which will contain the body text of the note).</p>
+ </li>
+</ol>
+
+<p>So with this simple database schema set up, when we start adding records to the database each one will be represented as an object along these lines:</p>
+
+<pre class="brush: js notranslate"><span class="message-body-wrapper"><span class="message-flex-body"><span class="devtools-monospace message-body"><span class="objectBox objectBox-object"><span class="objectLeftBrace">{
+ </span><span class="nodeName">title</span><span class="objectEqual">: </span><span class="objectBox objectBox-string">"Buy milk"</span>,
+ <span class="nodeName">body</span><span class="objectEqual">: </span><span class="objectBox objectBox-string">"Need both cows milk and soya."</span>,
+ <span class="nodeName">id</span><span class="objectEqual">: </span><span class="objectBox objectBox-number">8</span></span></span></span></span><span class="message-body-wrapper"><span class="message-flex-body"><span class="devtools-monospace message-body"><span class="objectBox objectBox-object"><span class="objectRightBrace">
+}</span></span></span></span></span></pre>
+
+<h3 id="Добавляем_данные_в_базу_данных">Добавляем данные в базу данных</h3>
+
+<p>Now let's look at how we can add records to the database. This will be done using the form on our page.</p>
+
+<p>Below your previous event handler (but still inside the <code>window.onload</code> handler), add the following line, which sets up an <code>onsubmit</code> handler that runs a function called <code>addData()</code> when the form is submitted (when the submit {{htmlelement("button")}} is pressed leading to a successful form submission):</p>
+
+<pre class="brush: js notranslate">// Create an onsubmit handler so that when the form is submitted the addData() function is run
+form.onsubmit = addData;</pre>
+
+<p>Now let's define the <code>addData()</code> function. Add this below your previous line:</p>
+
+<pre class="brush: js notranslate">// Define the addData() function
+function addData(e) {
+ // prevent default - we don't want the form to submit in the conventional way
+ e.preventDefault();
+
+ // grab the values entered into the form fields and store them in an object ready for being inserted into the DB
+ let newItem = { title: titleInput.value, body: bodyInput.value };
+
+ // open a read/write db transaction, ready for adding the data
+ let transaction = db.transaction(['notes'], 'readwrite');
+
+ // call an object store that's already been added to the database
+ let objectStore = transaction.objectStore('notes');
+
+ // Make a request to add our newItem object to the object store
+ var request = objectStore.add(newItem);
+ request.onsuccess = function() {
+ // Clear the form, ready for adding the next entry
+ titleInput.value = '';
+ bodyInput.value = '';
+ };
+
+ // Report on the success of the transaction completing, when everything is done
+ transaction.oncomplete = function() {
+ console.log('Transaction completed: database modification finished.');
+
+ // update the display of data to show the newly added item, by running displayData() again.
+ displayData();
+ };
+
+ transaction.onerror = function() {
+ console.log('Transaction not opened due to error');
+ };
+}</pre>
+
+<p>This is quite complex; breaking it down, we:</p>
+
+<ul>
+ <li>Run {{domxref("Event.preventDefault()")}} on the event object to stop the form actually submitting in the conventional manner (this would cause a page refresh and spoil the experience).</li>
+ <li>Create an object representing a record to enter into the database, populating it with values from the form inputs. note that we don't have to explicitly include an <code>id</code> value — as we expained early, this is auto-populated.</li>
+ <li>Open a <code>readwrite</code> transaction against the <code>notes</code> object store using the {{domxref("IDBDatabase.transaction()")}} method. This transaction object allows us to access the object store so we can do something to it, e.g. add a new record.</li>
+ <li>Access the object store using the {{domxref("IDBTransaction.objectStore")}} property, saving it in the <code>objectStore</code> variable.</li>
+ <li>Add the new record to the database using {{domxref("IDBObjectStore.add()")}}. This creates a request object, in the same fashion as we've seen before.</li>
+ <li>Add a bunch of event handlers to the <code>request</code> and the <code>transaction</code> to run code at critical points in the lifecycle. Once the request has succeeded, we clear the form inputs ready for entering the next note. Once the transaction has completed, we run the <code>displayData()</code> function again to update the display of notes on the page.</li>
+</ul>
+
+<h3 id="Отображаем_данные">Отображаем данные</h3>
+
+<p>We've referenced <code>displayData()</code> twice in our code already, so we'd probably better define it. Add this to your code, below the previous function definition:</p>
+
+<pre class="brush: js notranslate">// Define the displayData() function
+function displayData() {
+ // Here we empty the contents of the list element each time the display is updated
+ // If you ddn't do this, you'd get duplicates listed each time a new note is added
+ while (list.firstChild) {
+ list.removeChild(list.firstChild);
+ }
+
+ // Open our object store and then get a cursor - which iterates through all the
+ // different data items in the store
+ let objectStore = db.transaction('notes').objectStore('notes');
+ objectStore.openCursor().onsuccess = function(e) {
+ // Get a reference to the cursor
+ let cursor = e.target.result;
+
+ // If there is still another data item to iterate through, keep running this code
+ if(cursor) {
+ // Create a list item, h3, and p to put each data item inside when displaying it
+ // structure the HTML fragment, and append it inside the list
+ let listItem = document.createElement('li');
+ let h3 = document.createElement('h3');
+ let para = document.createElement('p');
+
+ listItem.appendChild(h3);
+ listItem.appendChild(para);
+ list.appendChild(listItem);
+
+ // Put the data from the cursor inside the h3 and para
+ h3.textContent = cursor.value.title;
+ para.textContent = cursor.value.body;
+
+ // Store the ID of the data item inside an attribute on the listItem, so we know
+ // which item it corresponds to. This will be useful later when we want to delete items
+ listItem.setAttribute('data-note-id', cursor.value.id);
+
+ // Create a button and place it inside each listItem
+ let deleteBtn = document.createElement('button');
+ listItem.appendChild(deleteBtn);
+ deleteBtn.textContent = 'Delete';
+
+ // Set an event handler so that when the button is clicked, the deleteItem()
+ // function is run
+ deleteBtn.onclick = function(e) {
+ deleteItem(e);
+ };
+
+ // Iterate to the next item in the cursor
+ cursor.continue();
+ } else {
+ // Again, if list item is empty, display a 'No notes stored' message
+ if(!list.firstChild) {
+ let listItem = document.createElement('li');
+ listItem.textContent = 'No notes stored.'
+ list.appendChild(listItem);
+ }
+ // if there are no more cursor items to iterate through, say so
+ console.log('Notes all displayed');
+ }
+ };
+}</pre>
+
+<p>Again, let's break this down:</p>
+
+<ul>
+ <li>First we empty out the {{htmlelement("ul")}} element's content, before then filling it with the updated content. If you didn't do this, you'd end up with a huge list of duplicated content being added to with each update.</li>
+ <li>Next, we get a reference to the <code>notes</code> object store using {{domxref("IDBDatabase.transaction()")}} and {{domxref("IDBTransaction.objectStore")}} like we did in <code>addData()</code>, except here we are chaining them together in one line.</li>
+ <li>The next step is to use {{domxref("IDBObjectStore.openCursor()")}} method to open a request for a cursor — this is a construct that can be used to iterate over the records in an object store. We chain an <code>onsuccess</code> handler on to the end of this line to make the code more concise — when the cursor is successfully returned, the handler is run.</li>
+ <li>We get a reference to the cursor itself (an {{domxref("IDBCursor")}} object) using let <code>cursor = e.target.result</code>.</li>
+ <li>Next, we check to see if the cursor contains a record from the datastore (<code>if(cursor){ ... }</code>) — if so, we create a DOM fragment, populate it with the data from the record, and insert it into the page (inside the <code>&lt;ul&gt;</code> element). We also include a delete button that, when clicked, will delete that note by running the <code>deleteItem()</code> function, which we will look at in the next section.</li>
+ <li>At the end of the <code>if</code> block, we use the {{domxref("IDBCursor.continue()")}} method to advance the cursor to the next record in the datastore, and run the content of the <code>if</code> block again. If there is another record to iterate to, this causes it to be inserted into the page, and then <code>continue()</code> is run again, and so on.</li>
+ <li>When there are no more records to iterate over, <code>cursor</code> will return <code>undefined</code>, and therefore the <code>else</code> block will run instead of the <code>if</code> block. This block checks whether any notes were inserted into the <code>&lt;ul&gt;</code> — if not, it inserts a message to say no note was stored.</li>
+</ul>
+
+<h3 id="Удаляем_данные">Удаляем данные</h3>
+
+<p>As stated above, when a note's delete button is pressed, the note is deleted. This is achieved by the <code>deleteItem()</code> function, which looks like so:</p>
+
+<pre class="brush: js notranslate">// Define the deleteItem() function
+function deleteItem(e) {
+ // retrieve the name of the task we want to delete. We need
+ // to convert it to a number before trying it use it with IDB; IDB key
+ // values are type-sensitive.
+ let noteId = Number(e.target.parentNode.getAttribute('data-note-id'));
+
+ // open a database transaction and delete the task, finding it using the id we retrieved above
+ let transaction = db.transaction(['notes'], 'readwrite');
+ let objectStore = transaction.objectStore('notes');
+ let request = objectStore.delete(noteId);
+
+ // report that the data item has been deleted
+ transaction.oncomplete = function() {
+ // delete the parent of the button
+ // which is the list item, so it is no longer displayed
+ e.target.parentNode.parentNode.removeChild(e.target.parentNode);
+ console.log('Note ' + noteId + ' deleted.');
+
+ // Again, if list item is empty, display a 'No notes stored' message
+ if(!list.firstChild) {
+ let listItem = document.createElement('li');
+ listItem.textContent = 'No notes stored.';
+ list.appendChild(listItem);
+ }
+ };
+}</pre>
+
+<ul>
+ <li>The first part of this could use some explaining — we retrieve the ID of the record to be deleted using <code>Number(e.target.parentNode.getAttribute('data-note-id'))</code> — recall that the ID of the record was saved in a <code>data-note-id</code> attribute on the <code>&lt;li&gt;</code> when it was first displayed. We do however need to pass the attribute through the global built-in <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number">Number()</a> object, as it is currently a string, and otherwise won't be recognized by the database.</li>
+ <li>We then get a reference to the object store using the same pattern we've seen previously, and use the {{domxref("IDBObjectStore.delete()")}} method to delete the record from the database, passing it the ID.</li>
+ <li>When the database transaction is complete, we delete the note's <code>&lt;li&gt;</code> from the DOM, and again do the check to see if the <code>&lt;ul&gt;</code> is now empty, inserting a note as appropriate.</li>
+</ul>
+
+<p>So that's it! Your example should now work.</p>
+
+<p>If you are having trouble with it, feel free to <a href="https://mdn.github.io/learning-area/javascript/apis/client-side-storage/indexeddb/notes/">check it against our live example</a> (see the <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/notes/index.js">source code</a> also).</p>
+
+<h3 id="Храним_сложные_данные_через_IndexedDB">Храним сложные данные через IndexedDB</h3>
+
+<p>As we mentioned above, IndexedDB can be used to store more than just simple text strings. You can store just about anything you want, including complex objects such as video or image blobs. And it isn't much more difficult to achieve than any other type of data.</p>
+
+<p>To demonstrate how to do it, we've written another example called <a href="https://github.com/mdn/learning-area/tree/master/javascript/apis/client-side-storage/indexeddb/video-store">IndexedDB video store</a> (see it <a href="https://mdn.github.io/learning-area/javascript/apis/client-side-storage/indexeddb/video-store/">running live here also</a>). When you first run the example, it downloads all the videos from the network, stores them in an IndexedDB database, and then displays the videos in the UI inside {{htmlelement("video")}} elements. The second time you run it, it finds the videos in the database and gets them from there instead befoire displaying them — this makes subsequent loads much quicker and less bandwidth-hungry.</p>
+
+<p>Let's walk through the most interesting parts of the example. We won't look at it all — a lot of it is similar to the previous example, and the code is well-commented.</p>
+
+<ol>
+ <li>
+ <p>For this simple example, we've stored the names of the videos to fetch in an array of objects:</p>
+
+ <pre class="brush: js notranslate">const videos = [
+ { 'name' : 'crystal' },
+ { 'name' : 'elf' },
+ { 'name' : 'frog' },
+ { 'name' : 'monster' },
+ { 'name' : 'pig' },
+ { 'name' : 'rabbit' }
+];</pre>
+ </li>
+ <li>
+ <p>To start with, once the database is successfully opened we run an <code>init()</code> function. This loops through the different video names, trying to load a record identified by each name from the <code>videos</code> database.</p>
+
+ <p>If each video is found in the database (easily checked by seeing whether <code>request.result</code> evaluates to <code>true</code> — if the record is not present, it will be <code>undefined</code>), its video files (stored as blobs) and the video name are passed straight to the <code>displayVideo()</code> function to place them in the UI. If not, the video name is passed to the <code>fetchVideoFromNetwork()</code> function to ... you guessed it — fetch the video from the network.</p>
+
+ <pre class="brush: js notranslate">function init() {
+ // Loop through the video names one by one
+ for(let i = 0; i &lt; videos.length; i++) {
+ // Open transaction, get object store, and get() each video by name
+ let objectStore = db.transaction('videos').objectStore('videos');
+ let request = objectStore.get(videos[i].name);
+ request.onsuccess = function() {
+ // If the result exists in the database (is not undefined)
+ if(request.result) {
+ // Grab the videos from IDB and display them using displayVideo()
+ console.log('taking videos from IDB');
+ displayVideo(request.result.mp4, request.result.webm, request.result.name);
+ } else {
+ // Fetch the videos from the network
+ fetchVideoFromNetwork(videos[i]);
+ }
+ };
+ }
+}</pre>
+ </li>
+ <li>
+ <p>The following snippet is taken from inside <code>fetchVideoFromNetwork()</code> — here we fetch MP4 and WebM versions of the video using two separate {{domxref("fetch()", "WindowOrWorkerGlobalScope.fetch()")}} requests. We then use the {{domxref("blob()", "Body.blob()")}} method to extract each response's body as a blob, giving us an object representation of the videos that can be stored and displayed later on.</p>
+
+ <p>We have a problem here though — these two requests are both asynchronous, but we only want to try to display or store the video when both promises have fulfilled. Fortunately there is a built-in method that handles such a problem — {{jsxref("Promise.all()")}}. This takes one argument — references to all the individual promises you want to check for fulfillment placed in an array — and is itself promise-based.</p>
+
+ <p>When all those promises have fulfilled, the <code>all()</code> promise fulfills with an array containing all the individual fulfillment values. Inside the <code>all()</code> block, you can see that we then call the <code>displayVideo()</code> function like we did before to display the videos in the UI, then we also call the <code>storeVideo()</code> function to store those videos inside the database.</p>
+
+ <pre class="brush: js notranslate">let mp4Blob = fetch('videos/' + video.name + '.mp4').then(response =&gt;
+ response.blob()
+);
+let webmBlob = fetch('videos/' + video.name + '.webm').then(response =&gt;
+ response.blob()
+);;
+
+// Only run the next code when both promises have fulfilled
+Promise.all([mp4Blob, webmBlob]).then(function(values) {
+ // display the video fetched from the network with displayVideo()
+ displayVideo(values[0], values[1], video.name);
+ // store it in the IDB using storeVideo()
+ storeVideo(values[0], values[1], video.name);
+});</pre>
+ </li>
+ <li>
+ <p>Let's look at <code>storeVideo()</code> first. This is very similar to the pattern you saw in the previous example for adding data to the database — we open a <code>readwrite</code> transaction and get an object store reference our <code>videos</code>, create an object representing the record to add to the database, then simply add it using {{domxref("IDBObjectStore.add()")}}.</p>
+
+ <pre class="brush: js notranslate">function storeVideo(mp4Blob, webmBlob, name) {
+ // Open transaction, get object store; make it a readwrite so we can write to the IDB
+ let objectStore = db.transaction(['videos'], 'readwrite').objectStore('videos');
+ // Create a record to add to the IDB
+ let record = {
+ mp4 : mp4Blob,
+ webm : webmBlob,
+ name : name
+ }
+
+ // Add the record to the IDB using add()
+ let request = objectStore.add(record);
+
+ ...
+
+};</pre>
+ </li>
+ <li>
+ <p>Last but not least, we have <code>displayVideo()</code>, which creates the DOM elements needed to insert the video in the UI and then appends them to the page. The most interesting parts of this are those shown below — to actually display our video blobs in a <code>&lt;video&gt;</code> element, we need to create object URLs (internal URLs that point to the video blobs stored in memory) using the {{domxref("URL.createObjectURL()")}} method. Once that is done, we can set the object URLs to be the vaues of our {{htmlelement("source")}} element's <code>src</code> attributes, and it works fine.</p>
+
+ <pre class="brush: js notranslate">function displayVideo(mp4Blob, webmBlob, title) {
+ // Create object URLs out of the blobs
+ let mp4URL = URL.createObjectURL(mp4Blob);
+ let webmURL = URL.createObjectURL(webmBlob);
+
+ ...
+
+ let video = document.createElement('video');
+ video.controls = true;
+ let source1 = document.createElement('source');
+ source1.src = mp4URL;
+ source1.type = 'video/mp4';
+ let source2 = document.createElement('source');
+ source2.src = webmURL;
+ source2.type = 'video/webm';
+
+ ...
+}</pre>
+ </li>
+</ol>
+
+<h2 id="Оффлайн_хранение_данных">Оффлайн хранение данных</h2>
+
+<p>Пример ниже показывает, как создать приложение, которое будет хранить данные большого объема в хранилище IndexedDB, избегая необходимости скачивать их повторно. Это важное улучшение пользовательского опыта, но есть одно замечание — основной HTML, CSS, и файлы JavaScript все еще нужно загружать каждый раз при запросе сайта, это значит, что данный пример не будет работать при отсутствии сетевого соединения.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/15759/ff-offline.png" style="border-style: solid; border-width: 1px; display: block; height: 307px; margin: 0px auto; width: 765px;"></p>
+
+<p>Это тот случай, когда <a href="/en-US/docs/Web/API/Service_Worker_API">Service workers</a> и <a href="/en-US/docs/Web/API/Cache">Cache API</a> приходят на помощь.</p>
+
+<p>Сервис-воркер это файл JavaScript, который регистрируется на конкретном источнике (веб-сайте или части сайта на конкретном домене) при обращении браузером. После регистрации, он может управлять страницами на этом источнике. Воркер находится между загруженной страницей и сетевым соединением, перехватывая сетевые запросы источника.</p>
+
+<p>Когда worker перехватывает запрос, он может делать многие вещи (смотри <a href="/en-US/docs/Web/API/Service_Worker_API#Other_use_case_ideas">идеи для использования сервис-воркеров</a>), но классический пример это сохранение сетевых ответов и затем доступ к ним при запросе, вместо запросов по сети. В результате, это позволяет сделать веб-сайт полностью работающим в офлайне.</p>
+
+<p><a href="/en-US/docs/Web/API/Cache">Cache API</a> это еще один механизм хранения данных на клиенте с небольшим отличием — он разработан для хранения HTTP ответов, и прекрасно работает с сервис-воркерами.</p>
+
+<div class="note">
+<p><strong>Note</strong>: Service workers и Cache доступны в большинстве современных браузеров. В момент написания статьи, Safari еще не имел реализации, но скоро должна быть.</p>
+</div>
+
+<h3 id="Пример_сервис_воркера">Пример сервис воркера</h3>
+
+<p>Давайте взглянем на пример, чтобы дать вам немного мыслей о том, что из этого может выйти. Мы создали другую версию примера хранения видео, который использовался в предыдущей секции — эта функциональность идентична, за исключением того, что этот пример также сохраняет HTML, CSS, и JavaScript в Cache API посредством сервис-воркеров, что позволяет приложению работать полностью в офлайне!</p>
+
+<p>Смотри пример <a href="https://mdn.github.io/learning-area/javascript/apis/client-side-storage/cache-sw/video-store-offline/">хранилище видео с IndexedDB и сервис-воркером</a>, и его <a href="https://github.com/mdn/learning-area/tree/master/javascript/apis/client-side-storage/cache-sw/video-store-offline">исходный код</a>.</p>
+
+<h4 id="Регистрируем_сервис_воркер">Регистрируем сервис воркер</h4>
+
+<p>Первое, что нужно заметить, это дополнительный кусок кода, расположенный в основном JavaScript файле (см. <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/cache-sw/video-store-offline/index.js">index.js</a>). Первое,что мы делаем, это проверка на то, что <code>serviceWorker</code> доступен в объекте {{domxref("Navigator")}}. Если этот так, тогда мы знаем, что как минимум, базовые функции сервис-воркера доступны. Внутри проверки мы используем метод {{domxref("ServiceWorkerContainer.register()")}} для регистрации сервис-воркера, находящегося в файле <code>sw.js</code> на текущем источнике, таким образом, он может управлять страницами в текущей или внутренних директориях. Когда обещание выполнится, сервис-воркер считается зарегистрированным.</p>
+
+<pre class="brush: js notranslate"> // Регистрация сервис-воркера для обеспечения оффлайн доступности сайта
+
+ if('serviceWorker' in navigator) {
+ navigator.serviceWorker
+ .register('/learning-area/javascript/apis/client-side-storage/cache-sw/video-store-offline/sw.js')
+ .then(function() { console.log('Service Worker зарегистрирован'); });
+ }</pre>
+
+<div class="note">
+<p><strong>Примечание</strong>: Путь к файлу <code>sw.js</code> указан относительно корня сайта, а не JavaScript файла, содержащего основной код. Полный путь - <code>https://mdn.github.io/learning-area/javascript/apis/client-side-storage/cache-sw/video-store-offline/sw.js</code>. Корень -  <code>https://mdn.github.io</code>, и следовательно указываемый путь должен быть <code>/learning-area/javascript/apis/client-side-storage/cache-sw/video-store-offline/sw.js</code>. Если вы хотите использовать данный пример на своем сервере, вы также должны изменить путь к скрипту. Это довольно запутанно, но обязано так работать по причинам безопасности.</p>
+</div>
+
+<h4 id="Устанавливаем_сервис_воркер">Устанавливаем сервис воркер</h4>
+
+<p>В следующий раз, когда страница с сервис-воркером будет запрошена (например когда страница будет перезагружена), сервис-воркер запустится на этой странице и начнет контролировать её. Когда это произойдет, событие <code>install</code> будет вызвано в сервис-воркере; вы можете написать код внутри сервис-воркера, который будет вызван в процессе установки.</p>
+
+<p>Давайте взглянем на файл сервис-воркера <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/cache-sw/video-store-offline/sw.js">sw.js</a>. Вы можете видеть, что слушатель события <code>install</code> зарегистрирован на <code>self</code>. Ключевое слово <code>self</code> это способ ссылки на глобальную область видимости сервис-воркера из файла с сервис-воркером.</p>
+
+<p>Внутри обработчика <code>install</code> мы используем метод {{domxref("ExtendableEvent.waitUntil()")}}, доступном в объекте события, чтобы сигнализировать, что работа продолжается, и браузер не должен завершать установку, пока все задачи внутри блока не будут выполнены.</p>
+
+<p>Здесь мы видим Cache API в действии. Мы используем метод {{domxref("CacheStorage.open()")}} для открытия нового объекта кэша, в котором ответы могут быть сохранены (похоже на объект хранилища IndexedDB). Обещание выполнится с объектом {{domxref("Cache")}}, представляющим собой кэш <code>video-store</code> . Затем мы используем метод {{domxref("Cache.addAll()")}} для получения ресурсов и добавления ответов в кэш.</p>
+
+<pre class="brush: js notranslate">self.addEventListener('install', function(e) {
+ e.waitUntil(
+ caches.open('video-store').then(function(cache) {
+ return cache.addAll([
+ '/learning-area/javascript/apis/client-side-storage/cache-sw/video-store-offline/',
+ '/learning-area/javascript/apis/client-side-storage/cache-sw/video-store-offline/index.html',
+ '/learning-area/javascript/apis/client-side-storage/cache-sw/video-store-offline/index.js',
+ '/learning-area/javascript/apis/client-side-storage/cache-sw/video-store-offline/style.css'
+ ]);
+ })
+ );
+});</pre>
+
+<p>На этом установка завершена.</p>
+
+<h4 id="Отвечаем_на_последующие_запросы">Отвечаем на последующие запросы</h4>
+
+<p>Когда сервис-воркер зарегистрирован и установлен на странице HTML и сопутствующие ресурсы добавлены в кэш, все практически готово. Нужно сделать еще одну вещь - написать код для ответа на дальнейшие сетевые запросы.</p>
+
+<p>Это то, что делает вторая часть кода файла <code>sw.js</code>. Мы добавили еще один слушатель к сервис-воркеру в глобальной области видимости, который запускает функцию-обработчик при событии <code>fetch</code>. Это происходит всякий раз, когда браузер делает запрос ресурса в директорию, где зарегистрирован сервис-воркер.</p>
+
+<p>Внутри обработчика, мы сначала выводим в консоль URL запрашиваемого ресурса. Затем отдаем особый ответ на запрос, используя метод {{domxref("FetchEvent.respondWith()")}}.</p>
+
+<p>Внутри блока мы используем {{domxref("CacheStorage.match()")}} чтобы проверить, можно ли найти соответствующий запрос (т.е. совпадение по URL) в кэше. Обещание возвращает найденный ответ или <code>undefined</code>, если ничего не нашлось.</p>
+
+<p>Если совпадение нашлось, то просто возвращаем его как особый ответ. В противном случае, используем <a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch">fetch()</a> для запроса ресурса из сети.</p>
+
+<pre class="brush: js notranslate">self.addEventListener('fetch', function(e) {
+ console.log(e.request.url);
+ e.respondWith(
+ caches.match(e.request).then(function(response) {
+ return response || fetch(e.request);
+ })
+ );
+});</pre>
+
+<p>На этом все для нашего простого сервис-воркера. Используя подобный метод, вы можете сделать гораздо больше вещей — для получения доп. информации смотрите <a href="https://serviceworke.rs/">рецепты использования сервис-воркеров</a>. Спасибо Paul Kinlan за его статью <a href="https://developers.google.com/web/fundamentals/codelabs/offline/">Adding a Service Worker and Offline into your Web App</a>, которая вдохновила на написание данного примера.</p>
+
+<h4 id="Тестируем_наш_пример_оффлайн">Тестируем наш пример оффлайн</h4>
+
+<p>Для тестирования <a href="https://mdn.github.io/learning-area/javascript/apis/client-side-storage/cache-sw/video-store-offline/">примера</a>, вам нужно загрузить его несколько раз, чтобы быть уверенным, что сервис-воркер точно установлен. Когда это сделано, вы можете:</p>
+
+<ul>
+ <li>отключиться от сетевого соединения.</li>
+ <li>нажмите <em>Файл &gt; Перейти в офлайн, </em>если вы используете<em> </em>Firefox.</li>
+ <li>перейдите в инструменты разработчика, выберите <em>Application &gt; Service Workers</em>, нажмите галочку <em>Offline</em>, если используете Chrome.</li>
+</ul>
+
+<p>Если обновите страницу с примером снова, вы увидите, что все работает как обычно. Все данные хранятся в офлайн хранилище — ресурсы страницы в кэше, а видео в базе данных IndexedDB.</p>
+
+<h2 id="Итого">Итого</h2>
+
+<p>Это всё, пока что. Мы надеемся наш краткий обзор <code>client-side storage</code> окажется полезным для вас.</p>
+
+<h2 id="Также_стоит_почитать">Также стоит почитать</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Web/API/Web_Storage_API">Web storage API</a></li>
+ <li><a href="/en-US/docs/Web/API/IndexedDB_API">IndexedDB API</a></li>
+ <li><a href="/en-US/docs/Web/HTTP/Cookies">Cookies</a></li>
+ <li><a href="/en-US/docs/Web/API/Service_Worker_API">Service worker API</a></li>
+</ul>
+
+<p>{{PreviousMenu("Learn/JavaScript/Client-side_web_APIs/Video_and_audio_APIs", "Learn/JavaScript/Client-side_web_APIs")}}</p>
+
+<h2 id="В_этом_модуле">В этом модуле</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Introduction">Introduction to web APIs</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Manipulating_documents">Manipulating documents</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Fetching_data">Fetching data from the server</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Third_party_APIs">Third party APIs</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Drawing_graphics">Drawing graphics</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Video_and_audio_APIs">Video and audio APIs</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Client-side_storage">Client-side storage</a></li>
+</ul>
diff --git a/files/ru/learn/javascript/client-side_web_apis/fetching_data/index.html b/files/ru/learn/javascript/client-side_web_apis/fetching_data/index.html
new file mode 100644
index 0000000000..63d9010aab
--- /dev/null
+++ b/files/ru/learn/javascript/client-side_web_apis/fetching_data/index.html
@@ -0,0 +1,379 @@
+---
+title: Получение данных с сервера
+slug: Learn/JavaScript/Client-side_web_APIs/Fetching_data
+tags:
+ - AJAX
+ - API
+ - Fetch
+ - JavaScript
+ - XHR
+ - Новичку
+translation_of: Learn/JavaScript/Client-side_web_APIs/Fetching_data
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Client-side_web_APIs/Manipulating_documents", "Learn/JavaScript/Client-side_web_APIs/Third_party_APIs", "Learn/JavaScript/Client-side_web_APIs")}}</div>
+
+<p class="summary"><span lang="ru">Другой очень распространенной задачей в современных веб-сайтах и ​​приложениях является получение отдельных элементов данных с сервера для обновления разделов веб-страницы без необходимости загрузки всей новой страницы. Эта, казалось бы, небольшая деталь оказала огромное влияние на производительность и поведение сайтов, поэтому в этой статье мы объясним концепцию и рассмотрим технологии, которые делают это возможным, например XMLHttpRequest и API Fetch.</span></p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Необходимые условия:</th>
+ <td>Основы JavaScript (см. <a href="/en-US/docs/Learn/JavaScript/First_steps">первые шаги</a>, <a href="/en-US/docs/Learn/JavaScript/Building_blocks">структурные элементы</a>, <a href="/en-US/docs/Learn/JavaScript/Objects">объекты JavaScript</a>), <a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Introduction">основы клиентских API</a></td>
+ </tr>
+ <tr>
+ <th scope="row">Задача:</th>
+ <td>Узнать, как извлекать данные с сервера и использовать их для обновления содержимого веб-страницы.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="В_чем_проблема">В чем проблема?</h2>
+
+<p>Первоначальная загрузка страницы в Интернете была простой - вы отправляли запрос на сервер  web-сайта, и если всё работает, как и должно, то вся необходимая информация о странице будет загружена и отображена на вашем компьютере.</p>
+
+<p><img alt="A basic representation of a web site architecture" src="https://mdn.mozillademos.org/files/6475/web-site-architechture@2x.png" style="display: block; height: 134px; margin: 0px auto; width: 484px;"></p>
+
+<p>Проблема с этой моделью заключается в том, что всякий раз, когда вы хотите обновить любую часть страницы, например, чтобы отобразить новый набор продуктов или загрузить новую страницу, вам нужно снова загрузить всю страницу. Это очень расточительно и приводит к плохому пользовательскому опыту, особенно по мере того, как страницы становятся все более сложными.</p>
+
+<h3 id="Появление_Ajax">Появление Ajax</h3>
+
+<p>Это привело к созданию технологий, позволяющих веб-страницам запрашивать небольшие фрагменты данных (например, <a href="https://developer.mozilla.org/en-US/docs/Web/HTML">HTML</a>, {{glossary("XML")}}, <a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/JSON">JSON</a> или обычный текст) и отображать их только при необходимости, помогая решать проблему, описанную выше.</p>
+
+<p>Это достигается с помощью таких API, как {{domxref("XMLHttpRequest")}} или - более новой - <a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API">Fetch API</a>. Эти технологии позволяют веб-страницам напрямую обрабатывать запросы <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP">HTTP</a> для определенных ресурсов, доступных на сервере, и форматировать результирующие данные по мере необходимости перед их отображением.</p>
+
+<div class="note">
+<p><strong>Примечание</strong>: Вначале эта общая техника была известна как Асинхронный JavaScript и XML (Ajax), поскольку она, как правило, использовала {{domxref("XMLHttpRequest")}} для запроса данных XML. В наши дни это обычно не так (вы, скорее всего, будете использовать <code>XMLHttpRequest</code> или Fetch для запроса JSON), но результат все тот же, и термин «Ajax» по-прежнему часто используется для описания этой техники.</p>
+</div>
+
+<p><img alt="A simple modern architecture for web sites" src="https://mdn.mozillademos.org/files/6477/moderne-web-site-architechture@2x.png" style="display: block; height: 235px; margin: 0px auto; width: 559px;"></p>
+
+<p>Модель Ajax предполагает использование веб-API в качестве прокси для более разумного запроса данных, а не просто для того, чтобы браузер перезагружал всю страницу. Давайте подумаем о значении этого:</p>
+
+<ol>
+ <li>Перейдите на один из ваших любимых сайтов, богатых информацией, таких как Amazon, YouTube, CNN и т.д., и загрузите его.</li>
+ <li>Теперь найдите что-нибудь, например, новый продукт. Основной контент изменится, но большая часть информации, подобной заголовку, нижнему колонтитулу, навигационному меню и т. д., останется неизменной.</li>
+</ol>
+
+<p>Это действительно хорошо, потому что:</p>
+
+<ul>
+ <li>Обновления страницы намного быстрее, и вам не нужно ждать перезагрузки страницы, а это означает, что сайт работает быстрее и воспринимается более отзывчивым.</li>
+ <li>Меньше данных загружается при каждом обновлении, что означает меньшее потребление пропускной способности. Это не может быть такой большой проблемой на рабочем столе в широкополосном подключении, но это серьезная проблема на мобильных устройствах и в развивающихся странах, которые не имеют повсеместного быстрого интернет-сервиса.</li>
+</ul>
+
+<p>Чтобы ускорить работу, некоторые сайты также сохраняют необходимые файлы и данные на компьютере пользователя при первом обращении к сайту, а это означает, что при последующих посещениях они используют локальные версии вместо загрузки свежих копий,  как при первой загрузке страницы. Содержимое загружается с сервера только при его обновлении.</p>
+
+<p><img alt="A basic web app data flow architecture" src="https://mdn.mozillademos.org/files/6479/web-app-architecture@2x.png" style="display: block; height: 383px; margin: 0px auto; width: 562px;"></p>
+
+<h2 id="Основной_запрос_Ajax">Основной запрос Ajax</h2>
+
+<p>Давайте посмотрим, как обрабатывается такой запрос, используя как {{domxref ("XMLHttpRequest")}}, так и <a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API">Fetch</a>. В этих примерах мы будем запрашивать данные из нескольких текстовых файлов и использовать их для заполнения области содержимого.</p>
+
+<p>Этот набор файлов будет действовать как наша поддельная база данных; в реальном приложении мы с большей вероятностью будем использовать серверный язык, такой как PHP, Python или Node, чтобы запрашивать наши данные из базы данных. Здесь, однако, мы хотим сохранить его простым и сосредоточиться на стороне клиента.</p>
+
+<h3 id="XMLHttpRequest">XMLHttpRequest</h3>
+
+<p><code>XMLHttpRequest</code> (который часто сокращается до XHR) является довольно старой технологией сейчас - он был изобретен Microsoft в конце 1990-х годов и уже довольно долго стандартизирован в браузерах.</p>
+
+<ol>
+ <li>
+ <p>Чтобы начать этот пример, создайте локальную копию <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/fetching-data/ajax-start.html">ajax-start.html</a> и четырех текстовых файлов - <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/fetching-data/verse1.txt">verse1.txt</a>, <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/fetching-data/verse2.txt">verse2.txt</a>, <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/fetching-data/verse3.txt">verse3.txt</a> и <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/fetching-data/verse4.txt">verse4.txt</a> - в новом каталоге на вашем компьютере. В этом примере мы загрузим другое стихотворение (который вы вполне можете распознать) через XHR, когда он будет выбран в выпадающем меню.</p>
+ </li>
+ <li>
+ <p>Внутри элемента {{htmlelement("script")}} добавьте следующий код. В нем хранится ссылка на элементы {{htmlelement("select")}} и {{htmlelement("pre")}} в переменных и определяется {{domxref ("GlobalEventHandlers.onchange", "onchange")}} обработчика событий, так что, когда значение select изменяется, его значение передается вызываемой функции <code>updateDisplay()</code> в качестве параметра.</p>
+
+ <pre class="brush: js">var verseChoose = document.querySelector('select');
+var poemDisplay = document.querySelector('pre');
+
+verseChoose.onchange = function() {
+ var verse = verseChoose.value;
+ updateDisplay(verse);
+};</pre>
+ </li>
+ <li>
+ <p>Давайте определим нашу функцию <code>updateDisplay()</code>. Прежде всего, поставьте следующее ниже своего предыдущего блока кода - это пустая оболочка функции:</p>
+
+ <pre class="brush: js">function updateDisplay(verse) {
+
+};</pre>
+ </li>
+ <li>
+ <p>Мы начнем нашу функцию с создания относительного URL-адреса, указывающего на текстовый файл, который мы хотим загрузить и который понадобится нам позже. Значение элемента {{htmlelement("select")}} в любой момент совпадает с текстом внутри выбранного {{htmlelement("option")}} (если вы не укажете другое значение в атрибуте value) - например, «Verse 1». Соответствующий текстовый файл стиха является «verse1.txt» и находится в том же каталоге, что и файл HTML, поэтому будет использоваться только имя файла.</p>
+
+ <p>Тем не менее, веб-серверы, как правило, чувствительны к регистру, и имя файла не имеет символа "пробела". Чтобы преобразовать «Verse 1» в «verse1.txt», нам нужно преобразовать V в нижний регистр, удалить пробел и добавить .txt в конец. Это можно сделать с помощью {{jsxref("String.replace", "replace ()")}}, {{jsxref("String.toLowerCase", "toLowerCase ()")}} и простой <a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/Strings#Concatenating_strings">конкатенации строк</a>. Добавьте следующие строки внутри функции <code>updateDisplay()</code>:</p>
+
+ <pre class="brush: js">verse = verse.replace(" ", "");
+verse = verse.toLowerCase();
+var url = verse + '.txt';</pre>
+ </li>
+ <li>
+ <p>Чтобы начать создание запроса XHR, вам нужно создать новый объект запроса, используя конструктор {{domxref("XMLHttpRequest()")}}. Вы можете назвать этот объект так, как вам нравится, но мы будем называть его <code>request</code> (запросом), чтобы все было просто. Добавьте следующие ниже строки:</p>
+
+ <pre class="brush: js">var request = new XMLHttpRequest();</pre>
+ </li>
+ <li>
+ <p>Затем вам нужно использовать метод {{domxref("XMLHttpRequest.open", "open()")}}, чтобы указать, какой <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods">HTTP request method</a> использовать для запроса ресурса из сети и какой его URL-адрес. Мы просто используем метод <code><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET">GET</a></code> здесь и задаем URL как нашу переменную <code>url</code>. Добавьте это ниже вашей предыдущей строки:</p>
+
+ <pre class="brush: js">request.open('GET', url);</pre>
+ </li>
+ <li>
+ <p>Затем мы зададим тип ожидаемого ответа, который определяется как свойство {{domxref("XMLHttpRequest.responseType", "responseType")}} - как <code>text</code>. Здесь это не является абсолютно необходимым - XHR возвращает текст по умолчанию - но это хорошая идея, чтобы привыкнуть к настройке этого, если вы хотите получить другие типы данных в будущем. Добавьте следующее:</p>
+
+ <pre class="brush: js">request.responseType = 'text';</pre>
+ </li>
+ <li>
+ <p>Получение ресурса из сети - это {{glossary("asynchronous")}} операция, означающая, что вам нужно дождаться завершения этой операции (например, ресурс возвращается из сети), прежде чем вы сможете сделать что-либо с этим ответом, иначе будет выброшена ошибка. XHR позволяет вам обрабатывать это, используя обработчик события {{domxref("XMLHttpRequest.onload", "onload")}} - он запускается при возникновении события {{event("load")}} (когда ответ вернулся). Когда это произойдет, данные ответа будут доступны в свойстве <code>response</code> (ответ) объекта запроса XHR.</p>
+
+ <p>Добавьте следующее ниже вашего последнего дополнения. Вы увидите, что внутри обработчика события <code>onload</code> мы устанавливаем textContent <code>poemDisplay</code> (элемент {{htmlelement("pre")}}) в значение {{domxref("XMLHttpRequest.response", "request. response ")}}.</p>
+
+ <pre class="brush: js">request.onload = function() {
+ poemDisplay.textContent = request.response;
+};</pre>
+ </li>
+ <li>
+ <p>Вышеприведенная конфигурация запроса XHR  фактически не будет выполняться до тех пор, пока мы не вызовем метод {{domxref("XMLHttpRequest.send", "send()")}}. Добавьте следующее ниже вашего предыдущего дополнения для вызова функции:</p>
+
+ <pre class="brush: js">request.send();</pre>
+ </li>
+ <li>
+ <p>Одна из проблем с примером заключается в том, что он не покажет ни одного стихотворения, когда он впервые загружается. Чтобы исправить это, добавьте следующие две строки внизу вашего кода (чуть выше закрывающего тега <code>&lt;/script&gt;</code>), чтобы загрузить стих 1 по умолчанию и убедитесь, что элемент {{htmlelement("select")}} всегда показывает правильное значение:</p>
+
+ <pre class="brush: js">updateDisplay('Verse 1');
+verseChoose.value = 'Verse 1';</pre>
+ </li>
+</ol>
+
+<h3 id="Обслуживание_вашего_примера_с_сервера">Обслуживание вашего примера с сервера</h3>
+
+<p>Некоторые браузеры (включая Chrome) не будут запускать запросы XHR, если вы просто запускаете пример из локального файла. Это связано с ограничениями безопасности (для получения дополнительной информации о безопасности в Интернете, ознакомьтесь с <a href="/en-US/docs/Learn/Server-side/First_steps/Website_security">Website security</a>).</p>
+
+<p>Чтобы обойти это, нам нужно протестировать пример, запустив его через локальный веб-сервер. Чтобы узнать, как это сделать, прочитайте <a href="/en-US/docs/Learn/Common_questions/set_up_a_local_testing_server">Как настроить локальный тестовый сервер?</a></p>
+
+<h3 id="Fetch">Fetch</h3>
+
+<p>API-интерфейс Fetch - это, в основном, современная замена XHR - недавно он был представлен в браузерах для упрощения асинхронных HTTP-запросов в JavaScript, как для разработчиков, так и для других API, которые строятся поверх Fetch.</p>
+
+<p>Давайте преобразуем последний пример, чтобы использовать Fetch!</p>
+
+<ol>
+ <li>
+ <p>Сделайте копию своего предыдущего готового каталога примеров. (Если вы не работали над предыдущим упражнением, создайте новый каталог и внутри него создайте копии <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/fetching-data/xhr-basic.html">xhr-basic.html</a> и четырех текстовых файлов — <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/fetching-data/verse1.txt">verse1.txt</a>, <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/fetching-data/verse2.txt">verse2.txt</a>, <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/fetching-data/verse3.txt">verse3.txt</a> и <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/fetching-data/verse4.txt">verse4.txt</a>.)</p>
+ </li>
+ <li>
+ <p>Внутри функции <code>updateDisplay()</code> найдите код XHR:</p>
+
+ <pre class="brush: js">var request = new XMLHttpRequest();
+request.open('GET', url);
+request.responseType = 'text';
+
+request.onload = function() {
+ poemDisplay.textContent = request.response;
+};
+
+request.send();</pre>
+ </li>
+ <li>
+ <p>Замените весь XHR-код следующим:</p>
+
+ <pre class="brush: js">fetch(url).then(function(response) {
+ response.text().then(function(text) {
+ poemDisplay.textContent = text;
+ });
+});</pre>
+ </li>
+ <li>
+ <p>Загрузите пример в свой браузер (запустите его через веб-сервер), и он должен работать так же, как и версия XHR, при условии, что вы используете современный браузер.</p>
+ </li>
+</ol>
+
+<h4 id="Итак_что_происходит_в_коде_Fetch">Итак, что происходит в коде Fetch?</h4>
+
+<p>Прежде всего, мы вызываем метод {{domxref("WorkerOrWindowGlobalScope.fetch()", "fetch()")}}, передавая ему URL-адрес ресурса, который мы хотим получить. Это современный эквивалент {{domxref("XMLHttpRequest.open", "request.open()")}} в XHR, плюс вам не нужен эквивалент <code>.send()</code>.</p>
+
+<p>После этого вы можете увидеть метод {{jsxref("Promise.then", ".then()")}}, прикреплённый в конец <code>fetch()</code> - этот метод является частью {{jsxref("Promise","Promises")}} - современная функция JavaScript для выполнения асинхронных операций. <code>fetch()</code> возвращает обещание, которое разрешает ответ, отправленный обратно с сервера, - мы используем <code>.then()</code> для запуска некоторого последующего кода после того, как обещание будет разрешено, что является функцией, которую мы определили внутри нее. Это эквивалент обработчика события <code>onload</code> в XHR-версии.</p>
+
+<p>Эта функция автоматически передает ответ от сервера в качестве параметра, когда обещает <code>fetch()</code>. Внутри функции мы берем ответ и запускаем его метод {{domxref("Body.text", "text()")}}, который в основном возвращает ответ как необработанный текст. Это эквивалент <code>request.responseType = 'text'</code> в версии XHR.</p>
+
+<p>Вы увидите, что <code>text()</code>также возвращает обещание, поэтому мы привязываем к нему другой <code>.then()</code>, внутри которого мы определяем функцию для получения необработанного текста, который обещает решение <code>text()</code>.</p>
+
+<p>Внутри функции внутреннего обещания мы делаем то же самое, что и в версии XHR, - устанавливаем текстовое содержимое {{htmlelement("pre")}} в текстовое значение.</p>
+
+<h3 id="Помимо_обещаний">Помимо обещаний</h3>
+
+<p>Обещания немного запутывают первый раз, когда вы их встречаете, но не беспокойтесь об этом слишком долго. Через некоторое время вы привыкнете к ним, особенно, когда вы узнаете больше о современных JavaScript-API. Большинство из них в большей степени основаны на обещаниях.</p>
+
+<p>Давайте посмотрим на структуру обещаний сверху, чтобы увидеть, можем ли мы еще немного понять это:</p>
+
+<pre class="brush: js">fetch(url).then(function(response) {
+ response.text().then(function(text) {
+ poemDisplay.textContent = text;
+ });
+});</pre>
+
+<p>В первой строке говорится: «Получить ресурс, расположенный по адресу url» <code>(fetch(url)</code>) и «затем запустить указанную функцию, когда обещание будет разрешено» (<code>.then(function() { ... })</code>). «Resolve» означает «завершить выполнение указанной операции в какой-то момент в будущем». Указанная операция в этом случае заключается в извлечении ресурса с указанного URL (с использованием HTTP-запроса) и возврата ответа для нас, чтобы что-то сделать.</p>
+
+<p>Фактически, функция, переданная в <code>then()</code>, представляет собой кусок кода, который не запускается немедленно - вместо этого он будет работать в какой-то момент в будущем, когда ответ будет возвращен. Обратите внимание, что вы также можете сохранить свое обещание в переменной и цепочку {{jsxref("Promise.then", ".then()")}} вместо этого. Ниже код будет делать то же самое:</p>
+
+<pre class="brush: js">var myFetch = fetch(url);
+
+myFetch.then(function(response) {
+ response.text().then(function(text) {
+ poemDisplay.textContent = text;
+ });
+});</pre>
+
+<p>Поскольку метод <code>fetch()</code> возвращает обещание, которое разрешает HTTP-ответ, любая функция, которую вы определяете внутри <code>.then()</code>, прикованная к концу, будет автоматически передаваться как параметр. Вы можете вызвать параметр, который вам нравится - приведенный ниже пример будет работать:</p>
+
+<pre class="brush: js">fetch(url).then(function(dogBiscuits) {
+ dogBiscuits.text().then(function(text) {
+ poemDisplay.textContent = text;
+ });
+});</pre>
+
+<p>Но имеет смысл называть параметр тем, что описывает его содержимое!</p>
+
+<p>Теперь давайте сосредоточимся только на функции:</p>
+
+<pre class="brush: js">function(response) {
+ response.text().then(function(text) {
+ poemDisplay.textContent = text;
+ });
+}</pre>
+
+<p>Объект ответа имеет метод {{domxref("Body.text", "text()")}}, который берет необработанные данные, содержащиеся в теле ответа, и превращает его в обычный текст, который является форматом, который мы хотим в нем А также возвращает обещание (которое разрешает полученную текстовую строку), поэтому здесь мы используем другой {{jsxref("Promise.then", ".then()")}}, внутри которого мы определяем другую функцию, которая диктует что мы хотим сделать с этой текстовой строкой. Мы просто устанавливаем свойство <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent">textContent</a></code> элемента {{htmlelement("pre")}} нашего стихотворения равным текстовой строке, так что это получается довольно просто.</p>
+
+<p>Также стоит отметить, что вы можете напрямую связывать несколько блоков обещаний (<code>.then()</code>, но есть и другие типы) на конце друг друга, передавая результат каждого блока следующему блоку по мере продвижения по цепочке , Это делает обещания очень мощными.</p>
+
+<p>Следующий блок делает то же самое, что и наш оригинальный пример, но написан в другом стиле:</p>
+
+<pre class="brush: js">fetch(url).then(function(response) {
+ return response.text()
+}).then(function(text) {
+ poemDisplay.textContent = text;
+});</pre>
+
+<p>Многие разработчики любят этот стиль больше, поскольку он более плоский и, возможно, легче читать для более длинных цепочек обещаний - каждое последующее обещание приходит после предыдущего, а не внутри предыдущего (что может стать громоздким). Единственное отличие состоит в том, что мы должны были включить оператор <code><a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Return_values">return</a></code> перед <code>response.text()</code>, чтобы заставить его передать результат в следующую ссылку в цепочке.</p>
+
+<h3 id="Какой_механизм_следует_использовать">Какой механизм следует использовать?</h3>
+
+<p>Это действительно зависит от того, над каким проектом вы работаете. XHR существует уже давно и имеет отличную кросс-браузерную поддержку. Fetch and Promises, с другой стороны, являются более поздним дополнением к веб-платформе, хотя они хорошо поддерживаются в браузере, за исключением Internet Explorer и Safari (которые на момент написания Fetch были доступны в своем предварительный просмотр технологии).</p>
+
+<p>Если вам необходимо поддерживать старые браузеры, тогда может быть предпочтительным решение XHR. Если, однако, вы работаете над более прогрессивным проектом и не так обеспокоены старыми браузерами, то Fetch может быть хорошим выбором.</p>
+
+<p>Вам действительно нужно учиться - Fetch станет более популярным, так как Internet Explorer отказывается от использования (IE больше не разрабатывается, в пользу нового браузера Microsoft Edge), но вам может понадобиться XHR еще некоторое время.</p>
+
+<h2 id="Более_сложный_пример">Более сложный пример</h2>
+
+<p>Чтобы завершить статью, мы рассмотрим несколько более сложный пример, который показывает более интересные применения Fetch. Мы создали образец сайта под названием The Can Store - это вымышленный супермаркет, который продает только консервы. Вы можете найти этот пример <a href="https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/">в прямом эфире на GitHub</a> и <a href="https://github.com/mdn/learning-area/tree/master/javascript/apis/fetching-data/can-store">посмотреть исходный код</a>.</p>
+
+<p><img alt="A fake ecommerce site showing search options in the left hand column, and product search results in the right hand column." src="https://mdn.mozillademos.org/files/14779/can-store.png" style="display: block; margin: 0 auto;"></p>
+
+<p>По умолчанию на сайте отображаются все продукты, но вы можете использовать элементы управления формы в столбце слева, чтобы отфильтровать их по категориям, поисковому запросу или и тому и другому.</p>
+
+<p>Существует довольно много сложного кода, который включает фильтрацию продуктов по категориям и поисковым запросам, манипулирование строками, чтобы данные отображались правильно в пользовательском интерфейсе и т.д. Мы не будем обсуждать все это в статье, но вы можете найти обширные комментарии в коде (см. <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/fetching-data/can-store/can-script.js">can-script.js</a>).</p>
+
+<p>Однако мы объясним код Fetch.</p>
+
+<p>Первый блок, который использует Fetch, можно найти в начале JavaScript:</p>
+
+<pre class="brush: js">fetch('products.json').then(function(response) {
+ if(response.ok) {
+ response.json().then(function(json) {
+ products = json;
+ initialize();
+ });
+ } else {
+ console.log('Network request for products.json failed with response ' + response.status + ': ' + response.statusText);
+ }
+});</pre>
+
+<p>Это похоже на то, что мы видели раньше, за исключением того, что второе обещание находится в условном выражении. В этом случае мы проверяем, был ли возвращенный ответ успешным - свойство {{domxref("response.ok")}} содержит логическое значение, которое <code>true</code>, если ответ был в порядке (например, <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/200">200 meaning "OK"</a>) или <code>false</code>, если он не увенчался успехом.</p>
+
+<p>Если ответ был успешным, мы выполняем второе обещание - на этот раз мы используем {{domxref("Body.json", "json()")}}, а не {{domxref("Body.text", "text()")}}, так как мы хотим вернуть наш ответ как структурированные данные JSON, а не обычный текст.</p>
+
+<p>Если ответ не увенчался успехом, мы выводим сообщение об ошибке в консоль, в котором сообщается о сбое сетевого запроса, который сообщает о статусе сети и описательном сообщении ответа (содержащемся в {{domxref("response.status")}} и {{domxref("response.statusText")}}, соответственно). Конечно, полный веб-сайт будет обрабатывать эту ошибку более грациозно, отображая сообщение на экране пользователя и, возможно, предлагая варианты для исправления ситуации.</p>
+
+<p>Вы можете проверить сам случай отказа:</p>
+
+<ol>
+ <li>Создание локальной копии файлов примеров (загрузка и распаковка <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/fetching-data/can-store/can-store.zip?raw=true">the can-store ZIP file</a>)</li>
+ <li>Запустите код через веб-сервер (как описано выше, в {{anch("Serving your example from a server")}})</li>
+ <li>Измените путь к извлеченному файлу, например, «product.json» (т.е. убедитесь, что он написан неправильно)</li>
+ <li>Теперь загрузите индексный файл в свой браузер (например, через <code>localhost:8000</code>) и посмотрите в консоли разработчика браузера. Вы увидите сообщение в строке «Запрос сети для продуктов.json не удалось с ответом 404: Файл не найден»</li>
+</ol>
+
+<p>Второй блок Fetch можно найти внутри функции <code>fetchBlob()</code>:</p>
+
+<pre class="brush: js">fetch(url).then(function(response) {
+ if(response.ok) {
+ response.blob().then(function(blob) {
+ objectURL = URL.createObjectURL(blob);
+ showProduct(objectURL, product);
+ });
+ } else {
+ console.log('Network request for "' + product.name + '" image failed with response ' + response.status + ': ' + response.statusText);
+ }
+});</pre>
+
+<p>Это работает во многом так же, как и предыдущий, за исключением того, что вместо использования {{domxref("Body.json", "json()")}} мы используем {{domxref("Body.blob", "blob()")}} - в этом случае мы хотим вернуть наш ответ в виде файла изображения, а формат данных, который мы используем для этого - <a href="https://developer.mozilla.org/en-US/docs/Web/API/Blob">Blob</a> - этот термин является аббревиатурой от« Binary Large Object »и может в основном использоваться для представляют собой большие файловые объекты, такие как изображения или видеофайлы.</p>
+
+<p>После того как мы успешно получили наш blob, мы создаем URL-адрес объекта, используя {{domxref("URL.createObjectURL()", "createObjectURL()")}}. Это возвращает временный внутренний URL-адрес, указывающий на объект, указанный в браузере. Они не очень читаемы, но вы можете видеть, как выглядит, открывая приложение Can Store, Ctrl-/щелкнуть правой кнопкой мыши по изображению и выбрать опцию «Просмотр изображения» (которая может немного отличаться в зависимости от того, какой браузер вы ). URL-адрес объекта будет отображаться внутри адресной строки и должен выглядеть примерно так:</p>
+
+<pre>blob:http://localhost:7800/9b75250e-5279-e249-884f-d03eb1fd84f4</pre>
+
+<h3 id="Вызов_XHR_версия_the_Can_Store">Вызов: XHR версия the Can Store</h3>
+
+<p>Мы хотели бы, чтобы вы решили преобразовать версию приложения Fetch для использования XHR в качестве полезной части практики. Возьмите <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/fetching-data/can-store/can-store.zip?raw=true">копию ZIP файла</a> и попробуйте изменить JavaScript, если это необходимо.</p>
+
+<p>Некоторые полезные советы:</p>
+
+<ul>
+ <li>Вы можете найти полезный справочный материал {{domxref("XMLHttpRequest")}}.</li>
+ <li>Вам в основном нужно использовать тот же шаблон, что и раньше, в примере <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/fetching-data/xhr-basic.html">XHR-basic.html</a>.</li>
+ <li>Однако вам нужно будет добавить обработку ошибок, которые мы показали вам в версии Fetch Can Store:
+ <ul>
+ <li>Ответ найден в <code>request.response</code> после того, как событие <code>load</code> запущено, а не в обещании <code>then()</code>.</li>
+ <li>О наилучшем эквиваленте Fetch's <code>response.ok</code> в XHR следует проверить, является ли {{domxref("XMLHttpRequest.status","request.status")}} равным 200 или если {{domxref("XMLHttpRequest.readyState","request.readyState")}} равно 4.</li>
+ <li>Свойства для получения статуса и сообщения состояния одинаковы, но они находятся на объекте <code>request</code> (XHR), а не в объекте <code>response</code>.</li>
+ </ul>
+ </li>
+</ul>
+
+<div class="note">
+<p><strong>Примечание</strong>: Если у вас есть проблемы с этим, не стесняйтесь сравнить свой код с готовой версией на GitHub (<a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/fetching-data/can-store-xhr/can-script.js">см. исходник здесь</a>, а также <a href="https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store-xhr/">см. это в действии</a>).</p>
+</div>
+
+<h2 id="Резюме">Резюме</h2>
+
+<p>Это завершает нашу статью по извлечению данных с сервера. К этому моменту вы должны иметь представление о том, как начать работать как с XHR, так и с Fetch.</p>
+
+<h2 id="Смотрите_также">Смотрите также</h2>
+
+<p>Однако в этой статье обсуждается много разных тем, которые только поцарапали поверхность. Для получения более подробной информации по этим темам, попробуйте следующие статьи:</p>
+
+<ul>
+ <li><a href="/en-US/docs/AJAX/Getting_Started">Введение в Ajax</a></li>
+ <li><a href="/en-US/docs/Web/API/Fetch_API/Using_Fetch">Применение Fetch</a></li>
+ <li><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promises</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/JSON">Работа с JSON данными</a></li>
+ <li><a href="/en-US/docs/Web/HTTP/Overview">Обзор HTTP</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side">Программирование веб-сайта на стороне сервера</a></li>
+</ul>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Client-side_web_APIs/Manipulating_documents", "Learn/JavaScript/Client-side_web_APIs/Third_party_APIs", "Learn/JavaScript/Client-side_web_APIs")}}</div>
+
+<div>
+<h2 id="В_этом_модуле">В этом модуле</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Introduction">Введение в web API</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Manipulating_documents">Манипулирование документами</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Fetching_data">Получение данных с сервера</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Third_party_APIs">Сторонние API</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Drawing_graphics">Рисование графики</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Video_and_audio_APIs">Видео и аудио API</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Client-side_storage">Клиентское хранилище</a></li>
+</ul>
+</div>
diff --git a/files/ru/learn/javascript/client-side_web_apis/index.html b/files/ru/learn/javascript/client-side_web_apis/index.html
new file mode 100644
index 0000000000..b5e7493f19
--- /dev/null
+++ b/files/ru/learn/javascript/client-side_web_apis/index.html
@@ -0,0 +1,53 @@
+---
+title: Клиентский веб API
+slug: Learn/JavaScript/Client-side_web_APIs
+tags:
+ - API
+ - Articles
+ - Beginner
+ - CodingScripting
+ - DOM
+ - Graphics
+ - JavaScript
+ - Landing
+ - Learn
+ - Media
+ - Module
+ - NeedsTranslation
+ - TopicStub
+ - WebAPI
+ - data
+translation_of: Learn/JavaScript/Client-side_web_APIs
+---
+<div>{{LearnSidebar}}</div>
+
+<p class="summary">При написании клиентского JavaScript для приложений или веб-сайтов Вам не приходится слишком сильно углубляться, пока Вы не начнете использовать API — интерфейсы управления различными аспектами браузера или операционной системы на которой этот сайт работает, или же с данными с других веб-сайтов или сервисов. В этом модуле мы рассмотрим что API из себя представляет и как использовать самые распространенные из них, с которыми Вы можете столкнуться в разработке.</p>
+
+<h2 id="Прежде_чем_начать">Прежде чем начать</h2>
+
+<p>Убедитесь, что вы прочли и хорошо разбираетесь в следующих модулях (<a href="https://wiki.developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9F%D0%B5%D1%80%D0%B2%D1%8B%D0%B5_%D1%88%D0%B0%D0%B3%D0%B8">Первые шаги</a>, <a href="https://wiki.developer.mozilla.org/ru/docs/Learn/JavaScript/Building_blocks">Структурные элементы</a>, и <a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects">Введение в объекты</a>). Эти модули включали в себя простое использование API, так как зачастую без них сложно писать примеры клиентского кода JavaScript. В данном модуле мы предполагаем, что вы хорошо знакомы с основами JavaScript, и немного подробнее рассмотрим общие веб-API.</p>
+
+<p>Естественно знание <a href="/en-US/docs/Learn/HTML">HTML</a> и <a href="/en-US/docs/Learn/CSS">CSS</a> здесь также необходимо.</p>
+
+<div class="note">
+<p><strong>Примечание:</strong> Если вы работаете на устройстве, где у вас нет возможности создавать свои собственные файлы, вы можете проверить большинство примеров кода в онлайн-программах вроде <a href="http://jsbin.com/">JSBin</a> или <a href="https://thimble.mozilla.org/">Thimble</a>.</p>
+</div>
+
+<h2 id="Руководства">Руководства</h2>
+
+<dl>
+ <dt><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Introduction">Введение в различные web API</a></dt>
+ <dd>Прежде всего, мы начнем изучение API с основ - что это такое, как это работает, как вы используете их в своем коде и как они структурированы? Мы также рассмотрим, что представляют собой различные основные классы API, и как их можно использовать.</dd>
+ <dt><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Manipulating_documents">Управление документами</a></dt>
+ <dd><span id="result_box" lang="ru"><span>При написании веб-страниц и приложений Вы чаще всего </span></span><span lang="ru"><span>будете управлять каким-либо образом веб-документами. </span></span> <span id="result_box" lang="ru"><span>Обычно это делается с помощью Document Object Model (DOM), набора API-интерфейсов для управления HTML-разметкой и стилями, которые используют объект {{domxref ("Document")}}. </span></span><span id="result_box" lang="ru"><span>В этой статье мы рассмотрим, как использовать DOM, а также некоторые интересные API, которые могут изменить рабочую среду интересными способами.</span></span></dd>
+ <dt><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/Client-side_web_APIs/Fetching_data">Получение данных с сервера</a></dt>
+ <dd>Другой очень распространенной задачей в современных веб-сайтах и приложениях является получение отдельных элементов данных с сервера для обновления разделов веб-страницы без необходимости загрузки абсолютно новой страницы. Эта, казалось бы, небольшая деталь оказала огромное влияние на производительность и поведение сайтов, поэтому в этой статье мы объясним концепцию и рассмотрим технологии, которые позволяют это, например {{domxref("XMLHttpRequest")}} и <a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API">Fetch API</a>.</dd>
+ <dt><a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Third_party_APIs">Сторонние API</a></dt>
+ <dd>API, которые мы рассматривали до сих пор, встроены в браузер, но не все API встроены в браузер. Многие крупные веб-сайты и сервисы, такие как Google Maps, Twitter, Facebook, PayPal и т.д. предоставляют API-интерфейсы, позволяющие разработчикам использовать свои данные (например, показывать ваш Twitter-поток в вашем блоге) или сервисы (например, отображение пользовательских карт Google на вашем сайте, или с помощью входа в систему Facebook для входа в систему пользователей). В этой статье рассматривается различие между API браузера и сторонними API и показано типичное использование последнего.</dd>
+ <dt><a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Drawing_graphics">Рисование графики</a></dt>
+ <dd>В браузере содержатся очень мощные инструменты графического программирования, начиная с языка Scalable Vector Graphics (<a href="https://developer.mozilla.org/en-US/docs/Web/SVG">SVG</a>) и заканчивая API для рисования элементов HTML {{htmlelement("canvas")}} (см. <a href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API">The Canvas API</a> и <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API">WebGL</a>). В статье содержится введение в Canvas API и дополнительные ресурсы, чтобы вы могли узнать больше.</dd>
+ <dt><a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Video_and_audio_APIs">Видео и аудио API</a></dt>
+ <dd>HTML5 поставляется с элементами для размещения мультимедийных материалов в документах - {{htmlelement("video")}} и {{htmlelement("audio")}} - которые, в свою очередь, имеют свои собственные API для управления воспроизведением, поиском и т. д. В статье показано, как выполнять общие задачи, такие как создание пользовательских элементов управления воспроизведением.</dd>
+ <dt><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/Client-side_web_APIs/Client-side_storage">Клиентское хранилище</a></dt>
+ <dd>Современные веб-браузеры имеют ряд различных технологий, которые позволяют хранить данные, связанные с веб-сайтами, и извлекать их, когда это необходимо, что позволяет вам сохранять данные в долгосрочной перспективе, сохранять сайты в автономном режиме и многое другое. В этой статье объясняются самые основы того, как они работают.</dd>
+</dl>
diff --git a/files/ru/learn/javascript/client-side_web_apis/introduction/index.html b/files/ru/learn/javascript/client-side_web_apis/introduction/index.html
new file mode 100644
index 0000000000..bc710c0d37
--- /dev/null
+++ b/files/ru/learn/javascript/client-side_web_apis/introduction/index.html
@@ -0,0 +1,277 @@
+---
+title: Введение в web APIs
+slug: Learn/JavaScript/Client-side_web_APIs/Introduction
+translation_of: Learn/JavaScript/Client-side_web_APIs/Introduction
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{NextMenu("Learn/JavaScript/Client-side_web_APIs/Manipulating_documents", "Learn/JavaScript/Client-side_web_APIs")}}</div>
+
+<p class="summary">Начнём с рассмотрения того что представляют собой API на высоком уровне и выясним, как они работают, как их использовать в своих программах и как они структурированы. Также рассмотрим основные виды API и их применение.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Необходимые знания:</th>
+ <td>Базовая компьютерная грамотность, понимание основ <a href="/en-US/docs/Learn/HTML">HTML</a> и <a href="/en-US/docs/Learn/CSS">CSS</a>,  основы JavaScript (см. <a href="/en-US/docs/Learn/JavaScript/First_steps">первые шаги</a>, <a href="/en-US/docs/Learn/JavaScript/Building_blocks">building blocks</a>, <a href="/en-US/docs/Learn/JavaScript/Objects">объекты JavaScript</a>).</td>
+ </tr>
+ <tr>
+ <th scope="row">Цель:</th>
+ <td>Познакомиться с API, выяснить что они могут делать и как их использовать.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Что_такое_API">Что такое API?</h2>
+
+<p>Интерфейс прикладного программирования (Application Programming Interfaces, APIs) - это готовые конструкции языка программирования, позволяющие разработчику строить сложный функционал с меньшими усилиями. Они "скрывают" более сложный код от программиста, обеспечивая простоту использования.</p>
+
+<p>Для лучшего понимания рассмотрим аналогию с домашними электросетями. Когда вы хотите использовать какой-то электроприбор, вы просто подключаете его к розетке, и всё работает. Вы не пытаетесь подключить провода напрямую к источнику тока — делать это бесполезно и, если вы не электрик, сложно и опасно.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14317/plug-socket.png" style="display: block; height: 472px; margin: 0px auto; width: 700px;"></p>
+
+<p><em>Image source: <a href="https://www.flickr.com/photos/easy-pics/9518184890/in/photostream/lightbox/">Overloaded plug socket</a> by <a href="https://www.flickr.com/photos/easy-pics/">The Clear Communication People</a>, on Flickr.</em></p>
+
+<p>Точно также, если мы хотим, например, программировать 3D графику, гораздо легче сделать это с использованием API, написанных на языках высокого уровня, таких как JavaScript или Python.</p>
+
+<div class="note">
+<p><strong>Note</strong>: См. также <a href="/en-US/docs/Glossary/API">API в словаре</a>.</p>
+</div>
+
+<h3 id="API_клиентской_части_JavaScript">API клиентской части JavaScript</h3>
+
+<p>Для JavaScript на стороне клиента, в частности, существует множество API. Они не являются частью языка, а построены с помощью встроенных функций JavaScript для того, чтобы увеличить ваши возможности при написании кода. Их можно разделить на две категории:</p>
+
+<ul>
+ <li><strong>API браузера</strong> встроены в веб-браузер и способны использовать данные браузера и компьютерной среды для осуществления более сложных действий с этими данными. К примеру, <a href="/en-US/docs/Web/API/Geolocation/Using_geolocation">API Геолокации (Geolocation API)</a> предоставляет простые в использовании конструкции JavaScript для работы с данными местоположения, так что вы сможете, допустим, отметить свое расположение на карте Google Map. На самом деле, в браузере выполняется сложный низкоуровневый код (например, на C++) для подключения к устройству GPS (или любому другому устройству геолокации), получения данных и передачи их браузеру для обработки вашей программой, но, как было сказано выше, эти детали скрыты благодаря API.</li>
+ <li><strong>Сторонние API</strong> не встроены в браузер по умолчанию. Такие API и информацию о них обычно необходимо искать в интернете. Например, <a href="https://dev.twitter.com/overview/documentation">Twitter API</a> позволяет размещать последние твиты (tweets) на вашем веб-сайте. В данном API определён набор конструкций, осуществляющих запросы к сервисам Twitter и возвращающих определённые данные.</li>
+</ul>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13508/browser.png" style="display: block; height: 511px; margin: 0px auto; width: 815px;"></p>
+
+<h3 id="Взаимодействие_JavaScript_API_и_других_средств_JavaScript">Взаимодействие JavaScript, API и других средств JavaScript</h3>
+
+<p>Итак, выше мы поговорили о том, что такое JavaScript API клиентской части и как они связаны с языком JavaScript. Давайте теперь тезисно запишем основные понятия и определим назначение других инструментов JavaScript:</p>
+
+<ul>
+ <li>JavaScript — Язык программирования сценариев высокого уровня, встроенный в браузер, позволяющий создавать функционал веб-страниц/приложений. Отметим, что JavaScript также доступен на других программных платформах, таких как <a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Introduction">Node</a>. Но пока не будем останавливаться на этом.</li>
+ <li>API браузера (Browser APIs) — конструкции, встроенные в браузер, построенные на основе языка JavaScript, предназначенные для облегчения разработки функционала.</li>
+ <li>Сторонние API (Third party APIs) — конструкции, встроенные в сторонние платформы (такие как Twitter, Facebook) позволяющие вам использовать часть функционала этих платформ в своих собственных веб-страницах/приложениях (например, показывать последние Твиты на вашей странице).</li>
+ <li>Библиотеки JavaScript — Обычно один или несколько файлов, содержащих <a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions#Custom_functions">пользовательские (custom) функции</a> . Такие файлы можно прикрепить к веб-странице, чтобы ускорить или предоставить инструменты для написания общего функционала. Примеры: jQuery, Mootools и React.</li>
+ <li>JavaScript фреймворки (frameworks) — Следующий шаг в развитии разработки после библиотек. Фреймворки JavaScript (такие как Angular и Ember) стремятся к тому, чтобы быть набором HTML, CSS, JavaScript и других технологий, после установки которого можно "писать" веб-приложение с нуля. Главное различие между фреймворками и библиотеками - "Обратное направление управления" ( “Inversion of Control” ). Вызов метода из библиотеки происходит по требованию разработчика. При использовании фреймворка - наоборот, фреймворк производит вызов кода разработчика.</li>
+</ul>
+
+<h2 id="На_что_способны_API">На что способны API?</h2>
+
+<p>Широкое разнообразие API в современных браузерах позволяет наделить ваше приложение большими возможностями. Достаточно посмотреть список на странице <a href="https://developer.mozilla.org/en-US/docs/Web/API">MDN APIs index page</a>.</p>
+
+<h3 id="Распространённые_API_браузера">Распространённые API браузера</h3>
+
+<p>В частности, к наиболее часто используемым категориям API (и которые мы рассмотрим далее в этом модуле) относятся :</p>
+
+<ul>
+ <li><strong>API для работы с документами</strong>, загруженными в браузер. Явный пример - <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model">DOM (Document Object Model) API</a>, позволяющий работать с HTML и CSS — создавать, удалять и изменять HTML, динамически изменять вид страницы и т.д. Любое всплывающее окно на странице или появляющееся "на ходу" содержимое - всё это благодаря DOM. Узнайте больше об этой категории API на странице <a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Manipulating_documents">Работа с документами</a>.</li>
+ <li><strong>API, принимающие данные от сервера</strong>, часто используются, чтобы обновить небольшие части веб-страницы. Эта, казалось бы, малая деталь оказывает огромное влияние на производительность и поведение сайтов, так как нет необходимости перезагружать всю страницу целиком, если вам нужно просто обновить список товаров или новых доступных историй. Это также сделает приложение или сайт более отзывчивым и "живым". Список API, благодаря которым это возможно, включает: <a href="https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest" title="XMLHttpRequest is an API that provides client functionality for transferring data between a client and a server. It provides an easy way to retrieve data from a URL without having to do a full page refresh. This enables a Web page to update just a part of the page without disrupting what the user is doing."><code>XMLHttpRequest</code></a> и <a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API">Fetch API</a>. Вы также могли встретить термин <strong>Ajax</strong>, описывающий эту технологию. Узнать больше об этой категории API на странице <a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Fetching_data">Получение данных от сервера</a>.</li>
+ <li><strong>API для работы с графикой</strong> широко поддерживаются браузерами,  самые популярные: <a href="/en-US/docs/Web/API/Canvas_API">Canvas</a> и <a href="/en-US/docs/Web/API/WebGL_API">WebGL</a>, позволяющие программно изменять данные о пикселях, содержащиеся в элементе HTML  {{htmlelement("canvas")}}  для создания 2D и 3D изображений. Например, вы можете нарисовать фигуры, скажем, прямоугольники или круги, импортировать изображение в canvas и применить к нему фильтры, такие как сепия или оттенки серого с помощью Canvas API, или создать сложное 3D-изображение с освещением и текстурами, используя WebGL. Такие API часто используют в сочетании с API создания анимационных циклов (таких как {{domxref("window.requestAnimationFrame()")}}) и другими для создания постоянно меняющегося изображения на экране, как в мультфильмах или играх .</li>
+ <li><strong><a href="https://developer.mozilla.org/en-US/Apps/Fundamentals/Audio_and_video_delivery">Аудио и Видео API</a></strong> как {{domxref("HTMLMediaElement")}}, <a href="/en-US/docs/Web/API/Web_Audio_API">Web Audio API</a>, и <a href="/en-US/docs/Web/API/WebRTC_API">WebRTC</a> позволяют делать действительно интересные вещи с мультимедиа. Например, создать собственный пользовательский интерфейс (User Interface, UI) для проигрывания аудио/видео, вывод на экран субтитров, записывать видео с веб-камеры для обработки в canvas (см. выше) или для передачи на другой компьютер в видео-конференции, применять звуковые эффекты к аудио-файлам (такие как gain, distortion, panning и т.д.).</li>
+ <li><strong>API устройств</strong> - в основном, API для обработки и считывания данных с современных устройств удобным для работы веб-приложений образом. Мы уже говорили об API Геолокации, позволяющем считать данные о местоположении устройства. Другие примеры включают уведомление пользователя о появившемся обновлении для веб-приложения с помощью системных уведомлений (см. <a href="/en-US/docs/Web/API/Notifications_API">Notifications API</a>) или вибрации (см. <a href="/en-US/docs/Web/API/Vibration_API">Vibration API</a>).</li>
+ <li><strong>API хранения данных на стороне пользователя</strong> приобретают всё большее распространение в веб-браузерах — возможность хранить информацию на стороне клиента очень полезна, когда необходимо создать приложение, которое будет сохранять своё состояние между перезагрузками страницы, или даже работать, когда устройство не в сети. В данный момент доступно немало таких API. Например, простое хранилище данных в формате имя/значение (name/value)  <a href="/en-US/docs/Web/API/Web_Storage_API">Web Storage API</a> или хранилище данных в формате таблиц <a href="/en-US/docs/Web/API/IndexedDB_API">IndexedDB API</a>.</li>
+</ul>
+
+<h3 id="Распространённые_сторонние_API">Распространённые сторонние API</h3>
+
+<p>Существует множество сторонних API; некоторые из наиболее популярных, которые вы рано или поздно будете использовать, включают:</p>
+
+<ul>
+ <li><a href="https://dev.twitter.com/overview/documentation">Twitter API</a> для добавления такого функционала, как показ последних твитов на сайте.</li>
+ <li><a href="https://developers.google.com/maps/">Google Maps API</a> для работы с картами на веб-странице (интересно, что Google Maps также использует этот API). Теперь это целый набор API, который может справляться с широким спектром задач, как свидетельствует <a href="https://developers.google.com/maps/documentation/api-picker">Google Maps API Picker</a>.</li>
+ <li><a href="https://developers.facebook.com/docs/">Набор Facebook API</a> позволяет использовать различные части платформы Facebook в вашем приложении, предоставляя, например, возможность входа в систему с логином Facebook, оплаты покупок в приложении, демонстрация целевой рекламы и т.д.</li>
+ <li><a href="https://developers.google.com/youtube/">YouTube API</a>, предоставляющий возможность встраивать видео с YouTube на вашем сайте, производить поиск, создавать плэйлисты и т.д.</li>
+ <li><a href="https://www.twilio.com/">Twilio API</a> - фреймворк для встраивания функционала голосовой и видео связи в вашем приложении, отправки SMS/MMS из приложения и т.д.</li>
+</ul>
+
+<div class="note">
+<p><strong>Note</strong>: Вы можете найти информацию о гораздо большем количестве сторонних API в <a href="http://www.programmableweb.com/category/all/apis">Каталоге Web API</a>.</p>
+</div>
+
+<h2 id="Как_работает_API">Как работает API?</h2>
+
+<p>Работа разных JavaScript API немного отличается, но, в основном, у них похожие функции и принцип работы.</p>
+
+<h3 id="Они_основаны_на_объектах">Они основаны на объектах</h3>
+
+<p>Взаимодействие с API в коде происходит через один или больше <a href="/en-US/docs/Learn/JavaScript/Objects">объектов JavaScript</a>, которые служат контейнерами для информации, с которой работает API (содержится в свойствах объекта), и реализуют функционал, который предоставляет API (содержится в методах объекта).</p>
+
+<div class="note">
+<p><strong>Note</strong>: Если вам ещё не известно как работают объекты, советуем вернуться назад и изучить модуль <a href="/en-US/docs/Learn/JavaScript/Objects">Основы объектов JavaScript</a> прежде чем продолжать.</p>
+</div>
+
+<p>Вернёмся к примеру с API Геолокации — очень простой API, состоящий из нескольких простых объектов:</p>
+
+<ul>
+ <li>{{domxref("Geolocation")}}, содержит три метода для контроля и получения геоданных.</li>
+ <li>{{domxref("Position")}}, предоставляет данные о местоположении устройства в заданный момент времени — содержит {{domxref("Coordinates")}} - объект, хранящий координаты и отметку о текущем времени.</li>
+ <li>{{domxref("Coordinates")}}, содержит много полезной информации о расположении устройства, включая широту и долготу, высоту, скорость и направление движения и т.д.</li>
+</ul>
+
+<p>Так как же эти объекты взаимодействуют? Если вы посмотрите на наш пример <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/introduction/maps-example.html">maps-example.html</a> (<a href="http://mdn.github.io/learning-area/javascript/apis/introduction/maps-example.html">see it live also</a>), вы увидите следующий код:</p>
+
+<pre class="brush: js notranslate">navigator.geolocation.getCurrentPosition(function(position) {
+ var latlng = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
+ var myOptions = {
+ zoom: 8,
+ center: latlng,
+ mapTypeId: google.maps.MapTypeId.TERRAIN,
+ disableDefaultUI: true
+ }
+ var map = new google.maps.Map(document.querySelector("#map_canvas"), myOptions);
+});</pre>
+
+<div class="note">
+<p><strong>Note</strong>: Когда вы впервые загрузите приведённый выше пример, появится диалоговое окно, запрашивающее разрешение на передачу данных о местонахождении этому приложению (см. раздел {{anch("У них есть дополнительные средства безопасности там, где это необходимо")}} далее в этой статье). Вам нужно разрешить передачу данных, чтобы иметь возможность отметить своё местоположение на карте. Если вы всё ещё не видите карту, возможно, требуется установить разрешения вручную; это делается разными способами в зависимости от вашего браузера; например, в Firefox перейдите &gt; <em>Tools</em> &gt; <em>Page Info</em> &gt; <em>Permissions</em>, затем измените настройки <em>Share Location</em>; в Chrome перейдите<em> Settings</em> &gt; <em>Privacy</em> &gt; <em>Show advanced settings</em> &gt; <em>Content settings</em> и измените настройки <em>Location</em>.</p>
+</div>
+
+<p>Во-первых, мы хотим использовать метод {{domxref("Geolocation.getCurrentPosition()")}}, чтобы получить текущее положение нашего устройства. Доступ к объекту браузера {{domxref("Geolocation")}} производится с помощью свойства {{domxref("Navigator.geolocation")}}, так что мы начнём с</p>
+
+<pre class="brush: js notranslate">navigator.geolocation.getCurrentPosition(function(position) { ... });</pre>
+
+<p>Это эквивалентно следующему коду</p>
+
+<pre class="brush: js notranslate">var myGeo = navigator.geolocation;
+myGeo.getCurrentPosition(function(position) { ... });</pre>
+
+<p>Но мы можем использовать точки, чтобы связать доступ к свойствам/методам объекта в одно выражение, уменьшая количество строк в программе.</p>
+
+<p>Метод {{domxref("Geolocation.getCurrentPosition()")}} имеет один обязательный параметр - анонимную функцию, которая запустится, когда текущее положение устройства будет успешно считано. Сама эта функция принимает параметр, являющийся объектом {{domxref("Position")}}, представляющим данные о текущем местоположении.</p>
+
+<div class="note">
+<p><strong>Note</strong>: Функция, которая передаётся другой функции в качестве параметра, называется <a href="/en-US/docs/Glossary/Callback_function">функцией обратного вызова (callback function)</a>.</p>
+</div>
+
+<p>Такой подход, при котором функция вызывается только тогда, когда операция была завершена, очень распространён в JavaScript API — убедиться, что операция была завершена прежде, чем пытаться использовать данные, которые она возвращает, в другой операции. Такие операции также называют асинхронными операциями (<strong><a href="/en-US/docs/Glossary/Asynchronous">asynchronous</a> operations)</strong>. Учитывая, что получение данных геолокации производится из внешнего устройства (GPS-устройства или другого устройства геолокации), мы не можем быть уверены, что операция считывания будет завершена вовремя и мы сможем незамедлительно использовать возвращаемые ею данные. Поэтому такой код не будет работать:</p>
+
+<pre class="brush: js example-bad notranslate">var position = navigator.geolocation.getCurrentPosition();
+var myLatitude = position.coords.latitude;</pre>
+
+<p>Если первая строка ещё не вернула результат, вторая вызовет ошибку из-за того, что данные геолокации ещё не стали доступны. По этой причине, API, использующие асинхронные операции, разрабатываются с использованием {{glossary("callback function")}}, или более современной системы <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Обещаний(Promises)</a>, которая появилась в ECMAScript 6 и широко используются в новых API.</p>
+
+<p>Мы совмещаем API Геолокации со сторонним API - Google Maps API, который используем для того, чтобы отметить расположение, возвращаемое  <code>getCurrentPosition()</code> , на Google Map. Чтобы Google Maps API стал доступен на нашей странице, мы включаем его в HTML документ:</p>
+
+<pre class="brush: html notranslate">&lt;script type="text/javascript" src="https://maps.google.com/maps/api/js?key=AIzaSyDDuGt0E5IEGkcE6ZfrKfUtE9Ko_de66pA"&gt;&lt;/script&gt;</pre>
+
+<p>Чтобы использовать этот API, во-первых создадим объект <code>LatLng</code> с помощью конструктора <code>google.maps.LatLng()</code> , принимающим данные геолокации {{domxref("Coordinates.latitude")}} и {{domxref("Coordinates.longitude")}} :</p>
+
+<pre class="brush: js notranslate">var latlng = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);</pre>
+
+<p>Этот объект сам является значением свойства <code>center</code> объекта настроек (options), который мы назвали <code>myOptions</code>. Затем мы создаём экземпляр объекта, представляющего нашу карту, вызывая конструктор <code>google.maps.Map()</code> и передавая ему два параметра — ссылку на элемент {{htmlelement("div")}}, на котором мы хотим отрисовывать карту (с ID <code>map_canvas</code>), и объект настроек (options), который мы определили выше.</p>
+
+<pre class="brush: js notranslate">var myOptions = {
+ zoom: 8,
+ center: latlng,
+ mapTypeId: google.maps.MapTypeId.TERRAIN,
+ disableDefaultUI: true
+}
+
+var map = new google.maps.Map(document.querySelector("#map_canvas"), myOptions);</pre>
+
+<p>Когда это сделано, наша карта отрисовывается.</p>
+
+<p>Последний блок кода демонстрирует два распространённых подхода, которые вы увидите во многих API:</p>
+
+<ul>
+ <li>Во-первых, объекты API обычно содержат конструкторы, которые вызываются для создания экземпляров объектов, используемых при написании программы.</li>
+ <li>Во-вторых, объекты API зачастую имеют несколько вариантов (options), которые можно настроить и получить именно ту среду для разработки, которую вы хотите. API конструкторы обычно принимают объекты вариантов (options) в качестве параметров, с помощью которых и происходит настройка.</li>
+</ul>
+
+<div class="note">
+<p><strong>Note</strong>: Не отчаивайтесь, если вы что-то не поняли из этого примера сразу. Мы рассмотрим использование сторонних API более подробно в следующих статьях.</p>
+</div>
+
+<h3 id="У_них_узнаваемые_точки_входа">У них узнаваемые точки входа</h3>
+
+<p>При использовании API убедитесь, что вы знаете где точка входа для API. В API Геолокации это довольно просто — это свойство {{domxref("Navigator.geolocation")}}, возвращающее объект браузера {{domxref("Geolocation")}}, внутри которого доступны все полезные методы геолокации.</p>
+
+<p>Найти точку входа Document Object Model (DOM) API ещё проще — при применении этого API используется объект {{domxref("Document")}}, или экземпляр элемента HTML, с которым вы хотите каким-либо образом взаимодействовать, к примеру:</p>
+
+<pre class="brush: js notranslate">var em = document.createElement('em'); // создаёт новый элемент em
+var para = document.querySelector('p'); // ссылка на существующий элемент p
+em.textContent = 'Hello there!'; // присвоение текстового содержимого
+para.appendChild(em); // встроить em внутрь para</pre>
+
+<p>Точки входа других API немного сложнее, часто подразумевается создание особого контекста, в котором будет написан код API. Например, объект контекста Canvas API создаётся получением ссылки на элемент {{htmlelement("canvas")}}, на котором вы хотите рисовать, а затем необходимо вызвать метод {{domxref("HTMLCanvasElement.getContext()")}}:</p>
+
+<pre class="brush: js notranslate">var canvas = document.querySelector('canvas');
+var ctx = canvas.getContext('2d');</pre>
+
+<p>Всё, что мы хотим сделать с canvas после этого, достигается вызовом свойств и методов объекта содержимого (content) (который является экземпляром {{domxref("CanvasRenderingContext2D")}}), например:</p>
+
+<pre class="brush: js notranslate">Ball.prototype.draw = function() {
+ ctx.beginPath();
+ ctx.fillStyle = this.color;
+ ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI);
+ ctx.fill();
+};</pre>
+
+<div class="note">
+<p><strong>Note</strong>: Вы можете увидеть этот код в действии в нашем <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/introduction/bouncing-balls.html">bouncing balls demo</a> (see it <a href="http://mdn.github.io/learning-area/javascript/apis/introduction/bouncing-balls.html">running live</a> also).</p>
+</div>
+
+<h3 id="Они_используют_события_для_управления_состоянием">Они используют события для управления состоянием</h3>
+
+<p>Мы уже обсуждали события ранее в этом курсе, в нашей статье <a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events">Introduction to events</a> — в этой статье детально описываются события на стороне клиента и их применение. Если вы ещё не знакомы с тем, как работают события клиентской части, рекомендуем прочитать эту статью прежде, чем продолжить.</p>
+
+<p>В некоторых API содержится ряд различных событий, в некоторых - событий нет. Свойства обработчика, позволяющие запускать функции при совершении какого-либо события по большей части перечислены в нашем материале отдельного раздела "Обработчики событий (Event handlers)". Как простой пример, экземпляры объекта <code><a href="/en-US/docs/Web/API/XMLHttpRequest">XMLHttpRequest</a></code> (каждый представляет собой HTTP-запрос к серверу на получение каких-либо ресурсов (resource)) имеют несколько доступных событий, например, событие <code>load</code> происходит, когда ответ с запрашиваемым ресурсом был успешно возвращён и доступен в данный момент.</p>
+
+<p>Следующий код содержит простой пример использования событий:</p>
+
+<pre class="brush: js notranslate">var requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';
+var request = new XMLHttpRequest();
+request.open('GET', requestURL);
+request.responseType = 'json';
+request.send();
+
+request.onload = function() {
+ var superHeroes = request.response;
+ populateHeader(superHeroes);
+ showHeroes(superHeroes);
+}</pre>
+
+<div class="note">
+<p><strong>Note</strong>: Вы можете увидеть этот код в действии в примере <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/introduction/ajax.html">ajax.html</a> (<a href="http://mdn.github.io/learning-area/javascript/apis/introduction/ajax.html">see it live</a> also).</p>
+</div>
+
+<p>В первых пяти строках мы задаём расположение ресурса, который хотим получить, создаём экземпляр объекта запроса с помощью конструктора <code>XMLHttpRequest()</code>, открываем HTTP-запрос <code>GET</code>, чтобы получить запрашиваемый ресурс, определяем, что мы хотим получить этот ресурс в формате json, после чего отсылаем запрос.</p>
+
+<p>Затем функция-обработчик <code>onload</code> определяет наши действия по обработке ответа сервера. Нам известно, что ответ успешно возвращён и доступен после наступления события load (и если не произойдёт ошибка), так что мы сохраняем ответ, содержащий возвращённый сервером объект JSON в переменной <code>superHeroes</code>, которую затем передаём двум различным функциям для дальнейшей обработки.</p>
+
+<h3 id="У_них_есть_дополнительные_средства_безопасности_там_где_это_необходимо">У них есть дополнительные средства безопасности там, где это необходимо</h3>
+
+<p>Функционал WebAPI подвержен тем же соображениям безопасности , что и JavaScript или другие веб-технологии (например, <a href="/en-US/docs/Web/Security/Same-origin_policy">same-origin policy</a>), но иногда они содержат дополнительные механизмы защиты. К примеру, некоторые из наиболее современных WebAPI работают только со страницами, обслуживаемыми через HTTPS в связи с передачей конфиденциальных данных (примеры: <a href="/en-US/docs/Web/API/Service_Worker_API">Service Workers</a> и <a href="/en-US/docs/Web/API/Push_API">Push</a>).</p>
+
+<p>К тому же, некоторые WebAPI запрашивают разрешение от пользователя, как только к ним происходит вызов в коде. В качестве примера, вы, возможно, встречали такое диалоговое окно при загрузке нашего примера <a href="/en-US/docs/Web/API/Geolocation">Geolocation</a> ранее:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14313/location-permission.png" style="border-style: solid; border-width: 1px; display: block; height: 188px; margin: 0px auto; width: 413px;"></p>
+
+<p><a href="/en-US/docs/Web/API/Notifications_API">Notifications API</a> запрашивает разрешение подобным образом:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14315/notification-permission.png" style="border-style: solid; border-width: 1px; display: block; margin: 0px auto;"></p>
+
+<p>Запросы разрешений необходимы для обеспечения безопасности пользователей — не будь их, сайты могли бы скрытно отследить ваше местоположение, не создавая множество надоедливых уведомлений.</p>
+
+<h2 id="Итоги">Итоги</h2>
+
+<p>На данном этапе, у вас должно сформироваться представление о том, что такое API, как они работают и как вы можете применить их в своём JavaScript коде. Вам наверняка не терпится начать делать по-настоящему интересные вещи с конкретными API, так вперёд! В следующий раз мы рассмотрим работу с документом с помощью Document Object Model (DOM).</p>
+
+<p>{{NextMenu("Learn/JavaScript/Client-side_web_APIs/Manipulating_documents", "Learn/JavaScript/Client-side_web_APIs")}}</p>
+
+<h2 id="В_этом_модуле">В этом модуле</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Introduction">Введение в web APIs</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Manipulating_documents">Manipulating documents</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Fetching_data">Fetching data from the server</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Third_party_APIs">Third party APIs</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Drawing_graphics">Drawing graphics</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Video_and_audio_APIs">Video and audio APIs</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Client-side_storage">Client-side storage</a></li>
+</ul>
diff --git a/files/ru/learn/javascript/client-side_web_apis/manipulating_documents/index.html b/files/ru/learn/javascript/client-side_web_apis/manipulating_documents/index.html
new file mode 100644
index 0000000000..e93334902a
--- /dev/null
+++ b/files/ru/learn/javascript/client-side_web_apis/manipulating_documents/index.html
@@ -0,0 +1,321 @@
+---
+title: Управление документами
+slug: Learn/JavaScript/Client-side_web_APIs/Manipulating_documents
+tags:
+ - API
+ - DOM
+ - Изучение
+ - Навигатор
+ - Новичек
+ - Окно
+translation_of: Learn/JavaScript/Client-side_web_APIs/Manipulating_documents
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Client-side_web_APIs/Introduction", "Learn/JavaScript/Client-side_web_APIs/Fetching_data", "Learn/JavaScript/Client-side_web_APIs")}}</div>
+
+<p class="summary">При написании веб-страниц и приложений вам придётся часто каким-либо образом управлять структурой документа. Обычно это делается с помощью Document Object Model (DOM), набора API для управления разметкой HTML и стилями, которая сильно использует объект {{domxref ("Document")}}. В этой статье мы подробно рассмотрим, как использовать DOM и некоторые другие интересные API, которые могут изменить вашу среду интересными способами.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Предпосылки:</th>
+ <td>Базовая компьютерная грамотность, базовое понимание HTML, CSS и JavaScript - включая объекты JavaScript.</td>
+ </tr>
+ <tr>
+ <th scope="row">Задача:</th>
+ <td>Познакомиться с основными DOM API и другими API, обычно связанными с DOM, и манипулированием документами</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Важные_элементы_веб-браузера">Важные элементы веб-браузера</h2>
+
+<p>Веб-браузеры - очень сложные части программного обеспечения с множеством движущихся частей, многие из которых не могут управляться или управляться веб-разработчиком с использованием JavaScript. Вы можете подумать, что такие ограничения - это плохо, но браузеры заблокированы по уважительным причинам (в основном ради безопасности). Представьте себе, что веб-сайт может получить доступ к вашим сохраненным паролям или другой конфиденциальной информации и войти на веб-сайты так, как если бы это были вы?</p>
+
+<p>Несмотря на ограничения, Web API по-прежнему дают нам доступ к множеству функциональных возможностей, которые позволяют нам многое делать с веб-страницами. Есть несколько действительно очевидных моментов, на которые вы будете регулярно ссылаться в своем коде. Рассмотрим следующую диаграмму, которая представляет основные части браузера, непосредственно участвующие в просмотре веб-страниц:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14557/document-window-navigator.png" style="display: block; margin: 0 auto;"></p>
+
+<ul>
+ <li>Окно - это вкладка браузера, в которую загружается веб-страница; это представлено в JavaScript объектом {{domxref("Window")}}. Используя методы, доступные для этого объекта, вы можете делать такие вещи, как возврат размера окна (см. {{Domxref("Window.innerWidth")}} и {{domxref("Window.innerHeight")}}), манипулировать документом, загруженным в этот window, хранить данные, специфичные для этого документа на стороне клиента (например, используя локальную базу данных или другой механизм хранения), присоединить обработчик событий (<a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#A_series_of_fortunate_events">event handler</a>) к текущему окну и многое другое.</li>
+ <li>Навигатор представляет состояние и идентификатор браузера (т. е. пользовательский агент), как он существует в Интернете. В JavaScript это представлено объектом {{domxref("Navigator")}}. Вы можете использовать этот объект для извлечения таких вещей, как геолокационная информация, предпочтительный язык пользователя, медиапоток с веб-камеры пользователя и т. д.</li>
+ <li>Документ (представленный DOM в браузерах) представляет собой фактическую страницу, загруженную в окно, и представлен в JavaScript объектом {{domxref("Document")}}. Вы можете использовать этот объект для возврата и обработки информации о HTML и CSS, содержащей документ, например, получить ссылку на элемент в DOM, изменить его текстовый контент, применить к нему новые стили, создать новые элементы и добавить их в текущий элемент как дочерний элемент, или даже вообще удалить его.</li>
+</ul>
+
+<p>В этой статье мы сосредоточимся главным образом на манипулировании документом, но мы покажем ещё несколько полезных моментов.</p>
+
+<h2 id="Объектная_модель_документа">Объектная модель документа</h2>
+
+<p>Документ, загруженный в каждый из ваших вкладок браузера, представлен объектной моделью документа. Это представление «древовидной структуры», созданное браузером, которое позволяет легко получить доступ к структуре HTML с помощью языков программирования - например, сам браузер использует его для применения стиля и другой информации к правильным элементам, поскольку он отображает страницу, а разработчики (как Вы) могут манипулировать DOM с JavaScript после того, как страница была отображена.</p>
+
+<p>Мы создали простую страницу примера в <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/document-manipulation/dom-example.html">dom-example.html</a> (<a href="https://mdn.github.io/learning-area/javascript/apis/document-manipulation/dom-example.html">см. также live</a>). Попробуйте открыть это в своем браузере - это очень простая страница, содержащая элемент {{htmlelement("section")}}, внутри которого вы можете найти изображение и абзац со ссылкой внутри. Исходный код HTML выглядит так:</p>
+
+<pre class="brush: html notranslate">&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+ &lt;head&gt;
+ &lt;meta charset="utf-8"&gt;
+ &lt;title&gt;Simple DOM example&lt;/title&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+ &lt;section&gt;
+ &lt;img src="dinosaur.png" alt="A red Tyrannosaurus Rex: A two legged dinosaur standing upright like a human, with small arms, and a large head with lots of sharp teeth."&gt;
+ &lt;p&gt;Here we will add a link to the &lt;a href="https://www.mozilla.org/"&gt;Mozilla homepage&lt;/a&gt;&lt;/p&gt;
+ &lt;/section&gt;
+ &lt;/body&gt;
+&lt;/html&gt;</pre>
+
+<p>DOM, с другой стороны, выглядит так:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14559/dom-screenshot.png" style="border-style: solid; border-width: 1px; display: block; margin: 0px auto;"></p>
+
+<div class="note">
+<p><strong>Примечание</strong>. Эта диаграмма дерева DOM была создана с использованием <a href="https://software.hixie.ch/utilities/js/live-dom-viewer/">Live DOM viewer</a> Яна Хиксона.</p>
+</div>
+
+<p>Вы можете видеть здесь, что каждый элемент и бит текста в документе имеют свою собственную запись в дереве - каждый из них называется <strong>узлом</strong> (<strong>node)</strong>. Вы также столкнетесь с различными терминами, используемыми для описания типа узла, и их положением в дереве относительно друг друга:</p>
+
+<ul>
+ <li><strong>Element node</strong>: элемент, как он существует в DOM.</li>
+ <li><strong>Root node</strong>: верхний узел в дереве, который в случае <code>HTML</code> всегда является узлом HTML (другие словари разметки, такие как SVG и пользовательский XML, будут иметь разные корневые элементы)..</li>
+ <li><strong>Child node</strong>: узел <em>непосредственно</em> внутри другого узла. Например, <code>IMG</code> является дочерним элементом <code>SECTION</code> в приведенном выше примере.</li>
+ <li><strong>Descendant node</strong> (узел потомок): узел внутри дочернего элемента. Например, <code>IMG</code> является дочерним элементом <code>SECTION</code> в приведенном выше примере, и он также является потомком для родителя <code>SECTION</code>. <code>IMG</code> не является ребенком <code>BODY</code>, так как он находится на двух уровнях ниже дерева в дереве, но он является потомком <code>BODY</code>.</li>
+ <li><strong>Parent node</strong>: узел, в котором текущий узел. Например, <code>BODY</code> является родительским узлом <code>SECTION</code> в приведенном выше примере.</li>
+ <li><strong>Sibling nodes</strong> (одноуровневый узел): узлы, которые расположены на одном уровне в дереве DOM. Например, <code>IMG</code> и <code>P</code> являются братьями и сестрами в приведенном выше примере.</li>
+ <li><strong>Text node</strong>: узел, содержащий текстовую строку.</li>
+</ul>
+
+<p>Полезно ознакомиться с этой терминологией перед тем, как работать с DOM, поскольку некоторые термины кода, с которыми вы столкнетесь, используют их.. Возможно, вы уже сталкивались с ними, если вы изучали CSS (например, селектор потомков, дочерний селектор).</p>
+
+<h2 id="Активное_обучение_основы_управления_структурой_DOM">Активное обучение: основы управления структурой DOM</h2>
+
+<p>Чтобы начать изучение по управлению структуры DOM, давайте начнем с практического примера.</p>
+
+<ol>
+ <li>Возьмите локальную копию страницы <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/document-manipulation/dom-example.html">dom-example.html page</a> и изображение, которое вместе с ним.</li>
+ <li>Добавьте элемент <code>&lt;script&gt;&lt;/script&gt;</code> чуть выше закрывающего тега <code>&lt;/body&gt;</code>.</li>
+ <li>Чтобы управлять элементом внутри DOM, вам сначала нужно выбрать его и сохранить ссылку на него внутри переменной. Внутри вашего скриптового элемента добавьте следующую строку:
+ <pre class="brush: js notranslate">var link = document.querySelector('a');</pre>
+ </li>
+ <li>Теперь у нас есть ссылка на элемент, хранящаяся в переменной, мы можем начать ее манипулировать с использованием доступных ему свойств и методов (они определены на таких интерфейсах, как {{domxref("HTMLAnchorElement")}} в случае {{htmlelement ("a")}}, его более общий родительский интерфейс {{domxref ("HTMLElement")}} и {{domxref("Node")}} - который представляет все узлы в DOM). Прежде всего, давайте изменим текст внутри ссылки, обновив значение свойства {{domxref("Node.textContent")}}. Добавьте следующую строку ниже предыдущей:
+ <pre class="brush: js notranslate">link.textContent = 'Mozilla Developer Network';</pre>
+ </li>
+ <li>Мы также должны изменить URL-адрес, на который указывает ссылка, чтобы он не попадал в неправильное место при нажатии. Добавьте следующую строку, опять внизу:
+ <pre class="brush: js notranslate">link.href = 'https://developer.mozilla.org';</pre>
+ </li>
+</ol>
+
+<div>
+<p>Обратите внимание, что, как и во многих вещах в JavaScript, существует множество способов выбора элемента и хранения ссылки на него в переменной. {{domxref("Document.querySelector()")}} - рекомендуемый современный подход, который считается удобным, потому что он позволяет вам выбирать элементы с помощью селекторов CSS. Вышеупомянутый запрос <code>querySelector()</code> будет соответствовать первому элементу {{htmlelement("a")}}, который появляется в документе. Если вы хотите совместить и делать что-то с несколькими элементами, вы можете использовать {{domxref ("Document.querySelectorAll()")}}, который соответствует каждому элементу документа, который соответствует селектору и сохраняет ссылки на них в массиве <a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/Arrays">массиво</a>-подобном объекте, называемом NodeList.</p>
+
+<p>Существуют более старые методы для захвата ссылок на элементы, например:</p>
+
+<ul>
+ <li>{{domxref("Document.getElementById()")}}, который выбирает элемент с заданным значением атрибута <code>id</code>, например <code>&lt;p id="myId"&gt;Мой абзац&lt;/p&gt;</code>. Идентификатор передается функции как параметр, т.е. <code>var elementRef = document.getElementById('myId')</code>.</li>
+ <li>{{domxref("Document.getElementsByTagName()")}}, который возвращает массив, содержащий все элементы на странице данного типа, например <code>&lt;p&gt;</code>, <code>&lt;a&gt;</code> и т.д. Тип элемента передается к функции в качестве параметра, то есть <code>var elementRefArray = document.getElementsByTagName('p')</code>.</li>
+</ul>
+
+<p>Эти два работают в более старых браузерах, чем современные методы, такие как <code>querySelector()</code>, но не так удобны. Осмотритесь и вы увидите, что ещё можно найти!</p>
+</div>
+
+<h3 id="Создание_и_размещение_новых_узлов">Создание и размещение новых узлов</h3>
+
+<p>Вышесказанное дало вам немного вкуса от того, что вы можете сделать, но давайте продолжим и посмотрим, как мы можем создавать новые элементы.</p>
+
+<ol>
+ <li>Возвращаясь к текущему примеру, давайте начнем с захвата ссылки на наш элемент {{htmlelement("section")}} - добавьте следующий код внизу существующего скрипта (сделайте то же самое с другими строками):
+ <pre class="brush: js notranslate">var sect = document.querySelector('section');</pre>
+ </li>
+ <li>Теперь давайте создадим новый абзац, используя {{domxref("Document.createElement()")}} и передадим ему текстовое содержимое так же, как и раньше:
+ <pre class="brush: js notranslate">var para = document.createElement('p');
+para.textContent = 'We hope you enjoyed the ride.';</pre>
+ </li>
+ <li>Теперь вы можете добавить новый абзац в конце раздела, используя {{domxref("Node.appendChild()")}}:
+ <pre class="brush: js notranslate">sect.appendChild(para);</pre>
+ </li>
+ <li>Наконец, для этой части, давайте добавим текстовый узел в абзац, где находится ссылка, чтобы оформить предложение красиво. Сначала мы создадим текстовый узел, используя {{domxref("Document.createTextNode()")}}:
+ <pre class="brush: js notranslate">var text = document.createTextNode(' — the premier source for web development knowledge.');</pre>
+ </li>
+ <li>Теперь мы возьмем ссылку на абзац, в котором находится ссылка, и добавим к нему текстовый узел:
+ <pre class="brush: js notranslate">var linkPara = document.querySelector('p');
+linkPara.appendChild(text);</pre>
+ </li>
+</ol>
+
+<p>Это большая часть того, что вам нужно для добавления узлов в DOM - вы будете использовать эти методы при построении динамических интерфейсов (мы рассмотрим некоторые примеры позже).</p>
+
+<h3 id="Перемещение_и_удаление_элементов">Перемещение и удаление элементов</h3>
+
+<p>Могут быть моменты, когда вы хотите переместить узлы или вообще удалить их из DOM. Это вполне возможно.</p>
+
+<p>Если бы мы хотели переместить абзац со ссылкой внутри него в нижней части раздела, мы могли бы просто сделать это:</p>
+
+<pre class="brush: js notranslate">sect.appendChild(linkPara);</pre>
+
+<p>Это переводит абзац вниз в нижнюю часть раздела. Вы могли подумать, что это сделает вторую копию, но это не так - <code>linkPara</code> - ссылка на единственную копию этого абзаца. Если вы хотите сделать копию и добавить ее также, вам нужно будет использовать {{domxref("Node.cloneNode()")}}.</p>
+
+<p>Удаление узла довольно просто, по крайней мере, когда у вас есть ссылка на удаляемый узел и его родительский элемент. В нашем случае мы просто используем {{domxref("Node.removeChild()")}}, например:</p>
+
+<pre class="notranslate">sect.removeChild(linkPara);</pre>
+
+<p>Он становится немного сложнее, если вы хотите удалить узел, основанный только на ссылке на себя, что довольно часто. Нет способа сообщить узлу удалить себя, поэтому вам нужно будет сделать следующее.</p>
+
+<pre class="brush: js notranslate">linkPara.parentNode.removeChild(linkPara);</pre>
+
+<p>Попробуйте добавить вышеуказанные строки в свой код.</p>
+
+<h3 id="Управление_стилями">Управление стилями</h3>
+
+<p>Можно управлять стилями CSS с помощью JavaScript различными способами.</p>
+
+<p>Для начала вы можете получить список всех таблиц стилей, прикрепленных к документу, с помощью {{domxref("Document.stylesheets")}}, который возвращает массив объектов {{domxref("CSSStyleSheet")}}. Затем вы можете добавлять / удалять стили по желанию. Однако мы не будем расширять эти функции, потому что они являются несколько архаичным и трудным способом манипулирования стилем. Есть гораздо более простые способы.</p>
+
+<p>Первый способ - добавить встроенные стили непосредственно на элементы, которые вы хотите динамически стилизовать. Это делается с помощью свойства {{domxref("HTMLElement.style")}}, которое содержит встроенную информацию о стиле для каждого элемента документа. Вы можете установить свойства этого объекта для непосредственного обновления стилей элементов.</p>
+
+<ol>
+ <li>В качестве примера попробуйте добавить эти строки в наш текущий пример:
+ <pre class="brush: js notranslate">para.style.color = 'white';
+para.style.backgroundColor = 'black';
+para.style.padding = '10px';
+para.style.width = '250px';
+para.style.textAlign = 'center';</pre>
+ </li>
+ <li>Перезагрузите страницу, и вы увидите, что стили были применены к абзацу. Если вы посмотрите на этот параграф в инспекторе <a href="https://developer.mozilla.org/en-US/docs/Tools/Page_Inspector">Page Inspector/DOM inspector </a>вашего браузера, вы увидите, что эти строки действительно добавляют встроенные стили в документ:
+ <pre class="brush: html notranslate">&lt;p style="color: white; background-color: black; padding: 10px; width: 250px; text-align: center;"&gt;We hope you enjoyed the ride.&lt;/p&gt;</pre>
+ </li>
+</ol>
+
+<div class="note">
+<p>Примечание: Обратите внимание на то, как версии свойств JavaScript стилей CSS пишутся в нижнем регистре верблюжьего стиля (lower camel case), в то время как версии свойств стилей CSS используют дефисы  (например, <code>backgroundColor</code> и <code>background-color</code>). Убедитесь, что вы не перепутали их, иначе это не сработает.</p>
+</div>
+
+<p>Существует еще один распространенный способ динамического управления стилями вашего документа, который мы рассмотрим сейчас.</p>
+
+<ol>
+ <li>Удалите предыдущие пять строк, добавленных в JavaScript.</li>
+ <li>Добавьте в свой HTML-код следующее: {{htmlelement("head")}}:
+ <pre class="notranslate">&lt;style&gt;
+.highlight {
+ color: white;
+ background-color: black;
+ padding: 10px;
+ width: 250px;
+ text-align: center;
+}
+&lt;/style&gt;</pre>
+ </li>
+ <li>Теперь мы перейдем к очень полезному методу для общего манипулирования HTML - {{domxref("Element.setAttribute()")}} - это принимает два аргумента, атрибут, который вы хотите установить для элемента, и значение, которое вы хотите для его установки. В этом случае мы укажем имя класса выделения в нашем абзаце:
+ <pre class="brush: js notranslate">para.setAttribute('class', 'highlight');</pre>
+ </li>
+ <li>Обновите свою страницу, и вы не увидите изменений - CSS по-прежнему применяется к абзацу, но на этот раз, предоставив ему класс, который выбран нашим правилом CSS, а не как встроенные стили CSS.</li>
+</ol>
+
+<p>Какой метод вы выбираете, зависит от вас; оба имеют свои преимущества и недостатки. Первый метод принимает меньше настроек и хорош для простого использования, тогда как второй метод более пурист (без смешивания CSS и JavaScript, без встроенных стилей, которые рассматриваются как плохая практика). Когда вы начнете создавать более крупные приложения, вы, вероятно, начнете использовать второй метод больше, но это действительно зависит от вас.</p>
+
+<p>На данный момент мы не сделали ничего полезного! Нет смысла использовать JavaScript для создания статического контента - вы можете просто записать его в свой HTML и не использовать JavaScript. Это сложнее, чем HTML, и для создания вашего контента с помощью JavaScript также есть другие связанные с ним проблемы (например, не читаемые поисковыми системами).</p>
+
+<p>В следующих параграфах мы рассмотрим еще несколько практических применений DOM API.</p>
+
+<div class="note">
+<p>Примечание. Вы можете найти наш пример <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/document-manipulation/dom-example-manipulated.html">finished version of the dom-example.html</a> на GitHub (<a href="https://mdn.github.io/learning-area/javascript/apis/document-manipulation/dom-example-manipulated.html">см. также live</a>).</p>
+</div>
+
+<h2 id="Активное_обучение_динамический_список_покупок">Активное обучение: динамический список покупок</h2>
+
+<p>До сих пор мы действительно смотрели на использование функций {{domxref("Node")}} и {{domxref("Document")}} для управления документами, но нет причин, по которым вы не можете получить данные из других источников и использовать его в пользовательском интерфейсе. Вспомните нашу простую демонстрацию <a href="http://mdn.github.io/learning-area/javascript/apis/introduction/maps-example.html">maps-example.html</a> из последней статьи - там мы извлекли некоторые данные о местоположении и использовали ее для отображения карты вашей области. Вам просто нужно убедиться, что ваши данные в правильном формате; JavaScript упрощает работу, чем многие другие языки, будучи слабо типизированным - например, числа автоматически преобразуются в строки, когда вы хотите распечатать их на экране.</p>
+
+<p>В этом примере мы решим общую проблему: убедитесь, что ваше приложение имеет размер как окно, в котором он просматривается, независимо от его размера. Это часто полезно в таких ситуациях, как игры, где вы хотите использовать как можно большую площадь экрана, чтобы играть в игру.</p>
+
+<p>Для начала создайте локальную копию наших демо-файлов <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/document-manipulation/window-resize-example.html">window-resize-example.html</a> и <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/document-manipulation/bgtile.png">bgtile.png</a>. Откройте его и посмотрите - вы увидите, что у нас есть элемент {{htmlelement("div")}}, который покрывает небольшую часть экрана, на который нанесена фоновая плитка. Мы будем использовать это, чтобы представить нашу область пользовательского интерфейса приложения.</p>
+
+<ol>
+ <li>Прежде всего, давайте возьмем ссылку на div, а затем возьмем ширину и высоту окна просмотра (внутреннее окно, где отображается ваш документ) и сохраните их в переменных - эти два значения удобно содержатся в {{domxref("Window.innerWidth")}} и {{domxref("Window.innerHeight")}}. Добавьте следующие строки внутри существующего элемента {{htmlelement("script")}}:
+ <pre class="brush: js notranslate">var div = document.querySelector('div');
+var WIDTH = window.innerWidth;
+var HEIGHT = window.innerHeight;</pre>
+ </li>
+ <li>Затем мы динамически изменяем ширину и высоту div, равную ширине окна просмотра. Добавьте следующие две строки ниже своих первых:
+ <pre class="brush: js notranslate">div.style.width = WIDTH + 'px';
+div.style.height = HEIGHT + 'px';</pre>
+ </li>
+ <li>Сохраните и попробуйте обновить браузер - теперь вы должны увидеть, что div становится таким же большим, как ваш видовой экран, независимо от того, какой размер экрана вы используете. Если теперь вы попытаетесь изменить размер окна, чтобы увеличить его, вы увидите, что div остается одного размера - мы устанавливаем его только один раз.</li>
+ <li>Как насчет того, чтобы мы использовали событие, чтобы размер div изменялся при изменении размера окна? Объект {{domxref("Window")}} имеет событие, имеющееся на нем с именем resize, которое запускается каждый раз при изменении размера окна - давайте обратимся к нему через обработчик событий {{domxref("Window.onresize")}} и повторяйте наш размерный код каждый раз, когда он изменяется. Добавьте нижеследующую часть кода:
+ <pre class="brush: js notranslate">window.onresize = function() {
+ WIDTH = window.innerWidth;
+ HEIGHT = window.innerHeight;
+ div.style.width = WIDTH + 'px';
+ div.style.height = HEIGHT + 'px';
+}</pre>
+ </li>
+</ol>
+
+<div class="note">
+<p><strong>Примечание</strong>. Если у вас возникла проблема, посмотрите на наш <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/document-manipulation/window-resize-example-finished.html">законченный пример изменения размера окна</a> (<a href="https://mdn.github.io/learning-area/javascript/apis/document-manipulation/window-resize-example-finished.html">см. также live</a>).</p>
+</div>
+
+<h2 id="Активное_обучение_динамический_список_покупок_2">Активное обучение: динамический список покупок</h2>
+
+<p>Чтобы завершить статью, мы хотели бы задать вам небольшой вызов - мы хотим сделать простой пример списка покупок, который позволяет динамически добавлять элементы в список с помощью ввода формы и кнопки. Когда вы добавляете элемент на вход и нажимаете кнопку:</p>
+
+<ul>
+ <li>Элемент должен появиться в списке.</li>
+ <li>Каждому элементу должна быть предоставлена кнопка, которую можно нажать, чтобы удалить этот элемент из списка.</li>
+ <li>Вход должен быть опустошен и сфокусирован, чтобы вы могли ввести другой элемент.</li>
+</ul>
+
+<p>Готовое демо будет выглядеть примерно так:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14563/shopping-list.png" style="border-style: solid; border-width: 1px; display: block; height: 225px; margin: 0px auto; width: 369px;"></p>
+
+<p>Чтобы завершить упражнение, выполните следующие действия и убедитесь, что список ведет себя так, как описано выше.</p>
+
+<ol>
+ <li>Для начала загрузите копию нашего начального файла <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/document-manipulation/shopping-list.html">shopping-list.html</a> и скопируйте его где-нибудь. Вы увидите, что у него есть минимальный CSS, список с меткой, ввод и кнопка, пустой список и элемент {{htmlelement("script")}}. Вы будете делать все свои дополнения внутри скрипта.</li>
+ <li>Создайте три переменные, содержащие ссылки на список ({{htmlelement("ul")}}, {{htmlelement("input")}} и {{htmlelement("button")}} элементы.</li>
+ <li>Создайте <a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Functions">function</a>, которая будет запускаться в ответ на нажатие кнопки.</li>
+ <li>Внутри тела функции начните с сохранения текущего значения (<a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement#Properties">value</a>) входного элемента в переменной.</li>
+ <li>Затем очистите элемент ввода, установив его значение в пустую строку — <code>''</code>.</li>
+ <li>Создайте три новых элемента - элемент списка ({{htmlelement('li')}}), {{htmlelement('span')}} и {{htmlelement('button')}} и сохраните их в переменных.</li>
+ <li>Добавьте диапазон и кнопку в качестве дочерних элементов списка.</li>
+ <li>Установите текстовое содержимое диапазона на значение входного элемента, которое вы сохранили ранее, и текстовое содержимое кнопки «Удалить».</li>
+ <li>Добавить элемент списка в качестве дочернего списка.</li>
+ <li>Прикрепите обработчик события к кнопке удаления, чтобы при щелчке удалял весь элемент списка, внутри которого он находится.</li>
+ <li>Наконец, используйте метод <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus">focus()</a></code>, чтобы сфокусировать входной элемент, готовый для входа в следующий элемент списка покупок.</li>
+</ol>
+
+<div class="note">
+<p>Примечание: Если у вас возникла действительно сложная проблема, взгляните на наши примеры <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/document-manipulation/shopping-list-finished.html">finished shopping list</a> (<a href="http://mdn.github.io/learning-area/javascript/apis/document-manipulation/shopping-list-finished.html">see it running live also</a>.)</p>
+</div>
+
+<h2 id="Краткая_информация">Краткая информация</h2>
+
+<p>Мы закончили изучение документа и манипулирования DOM. На этом этапе вы должны понимать, что важная часть веб-браузера связана с управлением документами и другими аспектами веб-интерфейса пользователя. Самое главное, вы должны понять, что такое Document Object Model, и как манипулировать им для создания полезных функций.</p>
+
+<h2 id="Дополнительная_информация">Дополнительная информация</h2>
+
+<p>Есть много возможностей, которые можно использовать для управления вашими документами. Ознакомьтесь с некоторыми нашими рекомендациями и узнайте, что вы можете обнаружить:</p>
+
+<ul>
+ <li>{{domxref("Document")}}</li>
+ <li>{{domxref("Window")}}</li>
+ <li>{{domxref("Node")}}</li>
+ <li>{{domxref("HTMLElement")}}, {{domxref("HTMLInputElement")}}, {{domxref("HTMLImageElement")}}, etc.</li>
+</ul>
+
+<p>(Полный список веб-индексов API, задокументированных MDN: <a href="https://developer.mozilla.org/en-US/docs/Web/API">Web API index</a>)</p>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Client-side_web_APIs/Introduction", "Learn/JavaScript/Client-side_web_APIs/Fetching_data", "Learn/JavaScript/Client-side_web_APIs")}}</div>
+
+<div>
+<h2 id="В_этот_модуль_входит">В этот модуль входит</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Introduction">Introduction to web APIs</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Manipulating_documents">Manipulating documents</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Fetching_data">Fetching data from the server</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Third_party_APIs">Third party APIs</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Drawing_graphics">Drawing graphics</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Video_and_audio_APIs">Video and audio APIs</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Client-side_storage">Client-side storage</a></li>
+</ul>
+</div>
diff --git a/files/ru/learn/javascript/client-side_web_apis/third_party_apis/index.html b/files/ru/learn/javascript/client-side_web_apis/third_party_apis/index.html
new file mode 100644
index 0000000000..4977fe99c7
--- /dev/null
+++ b/files/ru/learn/javascript/client-side_web_apis/third_party_apis/index.html
@@ -0,0 +1,482 @@
+---
+title: Сторонние API
+slug: Learn/JavaScript/Client-side_web_APIs/Third_party_APIs
+tags:
+ - 3rd party
+ - API
+ - Third party
+ - Новичку
+translation_of: Learn/JavaScript/Client-side_web_APIs/Third_party_APIs
+---
+<div>{{LearnSidebar}}{{PreviousMenuNext("Learn/JavaScript/Client-side_web_APIs/Fetching_data", "Learn/JavaScript/Client-side_web_APIs/Drawing_graphics", "Learn/JavaScript/Client-side_web_APIs")}}</div>
+
+<p class="summary">API, которые мы рассмотрели до сих пор, встроены в браузер, но не все API таковы. Многие крупные веб-сайты и сервисы, такие как Google Maps, Twitter, Facebook, PayPal и т. д., Предоставляют API-интерфейсы, позволяющие разработчикам использовать свои данные (например, показывать ваш твиттер-поток в вашем блоге) или сервисы (например, отображение пользовательских карт Google на вашем сайте, или использование логина Facebook для входа в систему ваших пользователей). В этой статье рассматривается различие между API-интерфейсами браузера и сторонними API и показано типичное использование последних.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Необходимые условия:</th>
+ <td>Основы JavaScript (см. <a href="/en-US/docs/Learn/JavaScript/First_steps">первые шаги</a>, <a href="/en-US/docs/Learn/JavaScript/Building_blocks">структурные элементы</a>, <a href="/en-US/docs/Learn/JavaScript/Objects">объекты JavaScript</a>), the <a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Introduction">основы клиентских API</a></td>
+ </tr>
+ <tr>
+ <th scope="row">Задача:</th>
+ <td>Изучить, как работают сторонние API, и как использовать их для улучшения ваших сайтов.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Что_такое_сторонние_API">Что такое сторонние API?</h2>
+
+<p>Сторонние API - это API, предоставляемые третьими лицами — как правило, такими компаниями, как Facebook, Twitter, or Google — чтобы вы могли получить доступ к их функциям с помощью JavaScript и использовать его на своем собственном сайте. Как мы показали в нашей <a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Introduction">вводной статье об API</a>, одним из наиболее очевидных примеров является использование <a href="https://developers.google.com/maps/">Google Maps APIs</a> для отображения пользовательских карт на ваших страницах.</p>
+
+<p>Давайте снова посмотрим на наш пример карты (см. <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/introduction/maps-example.html">исходный код на GitHub</a>; <a href="https://mdn.github.io/learning-area/javascript/apis/introduction/maps-example.html">см. это в действии</a>),  и используем его для иллюстрации того, как сторонние API отличаются от API-интерфейсов браузера.</p>
+
+<div class="note">
+<p><strong>Примечание</strong>: По умолчанию использование сторонних API на вашем сайте позволит им отслеживать файлы cookie своих доменов, устанавливать файлы cookie в исходное состояние, получать заголовки ссылок, определяющие посещаемые страницы, и разрешать им выполнять JavaScript на страницах, на которых они загружаются с теми же разрешениями (например, выполнить запросы AJAX на ваши серверы с теми же кукисами сеанса). Должны быть оценены вопросы регулирования, безопасности и конфиденциальности.</p>
+</div>
+
+<div class="note">
+<p><strong>Примечание</strong>: Возможно, вы захотите сразу <a href="/en-US/docs/Learn#Getting_our_code_examples">получить все наши примеры кода</a>, в этом случае вы можете просто искать репо для файлов примеров, которые вам нужны в каждом разделе.</p>
+</div>
+
+<h3 id="Они_находятся_на_сторонних_серверах">Они находятся на сторонних серверах</h3>
+
+<p>API браузера встроены в браузер - вы можете получить к ним доступ сразу из JavaScript. Например, <a href="/en-US/docs/Web/API/Geolocation/Using_geolocation">API геолокации</a>, доступный в нашем примере, осуществляется с использованием свойства геолокации объекта <code><a href="/en-US/docs/Web/API/Navigator">Navigator</a></code>, которое возвращает объект <code><a href="/en-US/docs/Web/API/Geolocation">Geolocation</a></code>. Этот пример использует метод <code><a href="/en-US/docs/Web/API/Geolocation/getCurrentPosition">getCurrentPosition()</a></code> этого объекта, для запроса текущего положения устройства:</p>
+
+<pre class="brush: js">navigator.geolocation.getCurrentPosition(function(position) { ... });</pre>
+
+<p>Сторонние API, с другой стороны, расположены на сторонних серверах. Чтобы получить доступ к ним из JavaScript, вам сначала нужно подключиться к функциям API и сделать его доступным на вашей странице. Обычно это связано с первой ссылкой на библиотеку JavaScript, доступную на сервере через элемент {{htmlelement("script")}}, как показано в нашем примере:</p>
+
+<pre class="brush: js">&lt;script type="text/javascript" src="https://maps.google.com/maps/api/js?key=AIzaSyDDuGt0E5IEGkcE6ZfrKfUtE9Ko_de66pA"&gt;&lt;/script&gt;</pre>
+
+<p>Затем вы можете начать использовать объекты, доступные в этой библиотеке. Например:</p>
+
+<pre class="brush: js">var latlng = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
+var myOptions = {
+ zoom: 8,
+ center: latlng,
+ mapTypeId: google.maps.MapTypeId.TERRAIN,
+ disableDefaultUI: true
+}
+
+var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);</pre>
+
+<p>Здесь мы создаем новый объект <code>LatLng</code>, используя конструктор <code>google.maps.LatLng()</code>, который содержит широту и долготу местоположения, которое мы хотим показать, полученные из API геолокации. Затем мы создаем объект опций (<code>myOptions</code>), содержащий эту и другую информацию, связанную с отображением карты. Наконец, мы фактически создаем карту, используя конструктор <code>google.maps.Map()</code>, который принимает в качестве параметров элемент, на котором мы хотим нарисовать карту, и объект опций.</p>
+
+<p>Это вся информация, которую API Карт Google требует для построения простой карты. Сервер, к которому вы подключаетесь, обрабатывает все сложные вещи, такие как отображение правильных фрагментов карты для отображаемой области и т. д.</p>
+
+<div class="note">
+<p><strong>Примечание</strong>: Некоторые API обрабатывают доступ к их функциям несколько иначе, требуя от разработчика сделать HTTP-запрос (см. <a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Fetching_data">Получение данных с сервера</a>) на определенный шаблон URL для получения определенных данных. Они называются RESTful API, и мы покажем пример этого позже в статье.</p>
+</div>
+
+<h3 id="Разрешения_обрабатываются_по-разному">Разрешения обрабатываются по-разному</h3>
+
+<p>Безопасность API-интерфейсов браузеров, как правило, обрабатывается запросами разрешения, как <a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Introduction#They_have_additional_security_mechanisms_where_appropriate">описано в нашей первой статье</a>. Целью этого является то, что пользователь знает, что происходит на сайтах, которые он посещает, и с меньшей вероятностью может стать жертвой того, кто использует API, злонамеренно.</p>
+
+<p>Сторонние API имеют немного другую систему разрешений - они, как правило, используют ключевые коды, чтобы позволить разработчикам получить доступ к функциям API. Просмотрите URL-адрес библиотеки API Карт Google, с которой мы связались:</p>
+
+<pre>https://maps.google.com/maps/api/js?key=AIzaSyDDuGt0E5IEGkcE6ZfrKfUtE9Ko_de66pA</pre>
+
+<p>Параметр URL, указанный в конце URL-адреса, является ключом разработчика - разработчик приложения должен применять его для получения ключа, а затем включать его в свой код определенным образом, чтобы иметь доступ к функциям API. В случае с Картами Google (и другими API Google) вы подаете заявку на получение ключа на <a href="https://console.cloud.google.com/">Google Cloud Platform</a>.</p>
+
+<p>Другие API могут потребовать, чтобы вы включили ключ немного по-другому, но шаблон для большинства из них довольно схож. <br>
+  <br>
+ Требование к ключу заключается в том, что не каждый может использовать функциональность API без какой-либо подотчетности. Когда разработчик зарегистрировался для ключа, они затем известны поставщику API, и действие может быть предпринято, если они начинают делать что-то вредоносное с помощью API (например, отслеживать местоположение пользователей или пытаться спамить API с множеством запросов для остановки его работы, например). Самое простое действие - просто отменить их привилегии API.</p>
+
+<h2 id="Расширенный_пример_Карт_Google">Расширенный пример Карт Google</h2>
+
+<p>Теперь когда мы рассмотрели пример API Карт Google и посмотрели, как он работает, добавим еще несколько функций, чтобы показать, как использовать некоторые другие функции API.</p>
+
+<ol>
+ <li>
+ <p>Чтобы начать этот раздел, сделайте себе копию <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/third-party-apis/google-maps/maps_start.html">исходного файла Карт Google</a>, в новой папке. Если Вы уже <a href="/en-US/docs/Learn#Getting_our_code_examples">клонировали репозиторий примеров</a>, у вас уже есть копия этого файла, которую Вы можете найти в папке the <em>javascript/apis/third-party-apis/google-maps</em>.</p>
+ </li>
+ <li>
+ <p>Затем получите свой собственный ключ разработчика, выполнив следующие шаги:</p>
+
+ <ol>
+ <li>Перейдите в <a href="https://console.cloud.google.com/apis/dashboard">панель управления API-интерфейсом Google Cloud Platform</a>.</li>
+ <li>Создайте новый проект, если у вас его еще нет.</li>
+ <li>Нажмите кнопку <em>Enable API</em>.</li>
+ <li>Выберите <em>Google Maps JavaScript API</em>.</li>
+ <li>Нажмите кнопку <em>Enable</em>.</li>
+ <li>Нажмите <em>Create credentials</em>, затем выберите <em>API key</em>.</li>
+ <li>Скопируйте свой ключ API и замените существующий ключ в первом элементе {{htmlelement ('script')}} примера вашим собственным (фрагмент между <code>?key=</code> и меткой закрытия закрытия атрибута (<code>"</code>).)</li>
+ </ol>
+
+ <div class="note">
+ <p><strong>Примечание</strong>: Получение ключей API, связанных с Google, может быть немного затруднительным: в Менеджере API Google Cloud Platform много разных экранов, и рабочий процесс может немного отличаться в зависимости от того, как у вас уже установлена ​​учетная запись. Если у вас возникнут проблемы с этим шагом, мы будем рады помочь — <a href="/en-US/docs/Learn#Contact_us">Свяжитесь с нами</a>.</p>
+ </div>
+ </li>
+ <li>Откройте исходный файл Карт Google, найдите строку <code>INSERT-YOUR-API-KEY-HERE</code>, и замените ее фактическим ключом API, который вы получили из панели управления Google Cloud Platform API Manager.</li>
+</ol>
+
+<h3 id="Adding_a_custom_marker">Adding a custom marker</h3>
+
+<p>Adding a marker (icon) at a certain point on the map is easy — you just need to create a new marker using the <code>google.maps.Marker()</code> constructor, passing it an options object containing the position to display the marker at (as a <code>LatLng</code> object), and the <code>Map</code> object to display it on.</p>
+
+<ol>
+ <li>
+ <p>Add the following just below the <code>var map ...</code> line:</p>
+
+ <pre class="brush: js">var marker = new google.maps.Marker({
+ position: latlng,
+ map: map
+});</pre>
+
+ <p>Now if you refresh your page, you'll see a nice little marker pop up in the centre of the map. This is cool, but it is not exactly a custom marker — it is using the default marker icon.</p>
+ </li>
+ <li>
+ <p>To use a custom icon, we need to specify it when we create the marker, using its URL. First of all, add the following line above the previous block you added:</p>
+
+ <pre class="brush: js">var iconBase = 'https://maps.google.com/mapfiles/kml/shapes/';</pre>
+
+ <p>This defines the base URL where all the official Google Maps icons are stored (you could also specify your own icon location if you wished).</p>
+ </li>
+ <li>
+ <p>The icon location is specified in the <code>icon</code> property of the options object. Update the constructor like so:</p>
+
+ <pre class="brush: js">var marker = new google.maps.Marker({
+ position: latlng,
+ icon: iconBase + 'flag_maps.png',
+ map: map
+});</pre>
+
+ <p>Here we specify the icon property value as the <code>iconBase</code> plus the icon filename, to create the complete URL. Now try reloading your example and you'll see a custom marker displayed on your map!</p>
+ </li>
+</ol>
+
+<div class="note">
+<p><strong>Note</strong>: See <a href="https://developers.google.com/maps/documentation/javascript/custom-markers">Customizing a Google Map: Custom Markers</a> for more information.</p>
+</div>
+
+<div class="note">
+<p><strong>Note</strong>: See <a href="https://fusiontables.google.com/DataSource?dsrcid=308519#map:id=3">Map marker or Icon names</a> to find out what other icons are available, and see what their reference names are. Their file name will be the icon name they display when you click on them, with ".png" added on the end.</p>
+</div>
+
+<h3 id="Displaying_a_popup_when_the_marker_is_clicked">Displaying a popup when the marker is clicked</h3>
+
+<p>Another common use case for Google Maps is displaying more information about a place when its name or marker is clicked (popups are called <strong>info windows</strong> in the Google Maps API). This is also very simple to achieve, so let's have a look at it.</p>
+
+<ol>
+ <li>
+ <p>First of all, you need to specify a JavaScript string containing HTML that will define the content of the popup. This will be injected into the popup by the API and can contain just about any content you want. Add the following line below the <code>google.maps.Marker()</code> constructor definition:</p>
+
+ <pre class="brush: js">var contentString = '&lt;div id="content"&gt;&lt;h2 id="firstHeading" class="firstHeading"&gt;Custom info window&lt;/h2&gt;&lt;p&gt;This is a cool custom info window.&lt;/p&gt;&lt;/div&gt;';</pre>
+ </li>
+ <li>
+ <p>Next, you need to create a new info window object using the <code>google.maps.InfoWindow()</code> constructor. Add the following below your previous line:</p>
+
+ <pre class="brush: js">var infowindow = new google.maps.InfoWindow({
+ content: contentString
+});</pre>
+
+ <p>There are other properties available (see <a href="https://developers.google.com/maps/documentation/javascript/infowindows">Info Windows</a>), but here we are just specifying the <code>content</code> property in the options object, which points to the source of the content.</p>
+ </li>
+ <li>
+ <p>Finally, to get the popup to display when the marker is clicked, we use a simple click event handler. Add the following below the <code>google.maps.InfoWindow()</code> constructor:</p>
+
+ <pre class="brush: js">marker.addListener('click', function() {
+ infowindow.open(map, marker);
+});</pre>
+
+ <p>Inside the function, we simply invoke the infowindow's <code>open()</code> function, which takes as parameters the map you want to display it on, and the marker you want it to appear next to.</p>
+ </li>
+ <li>
+ <p>Now try reloading the example, and clicking on the marker!</p>
+ </li>
+</ol>
+
+<h3 id="Controlling_what_map_controls_are_displayed">Controlling what map controls are displayed</h3>
+
+<p>Inside the original <code>google.maps.Map()</code> constructor, you'll see the property <code>disableDefaultUI: true</code> specified. This disables all the standard UI controls you usually get on Google Maps.</p>
+
+<ol>
+ <li>
+ <p>Try setting its value to <code>false</code> (or just removing the line altogether) then reloading your example, and you'll see the map zoom buttons, scale indicator, etc.</p>
+ </li>
+ <li>
+ <p>Now undo your last change.</p>
+ </li>
+ <li>
+ <p>You can show or hide the controls in a more granular fashion by using other properties that specify single UI features. Try adding the following underneath the <code>disableDefaultUI: true</code> (remember to put a comma after <code>disableDefaultUI: true</code>, otherwise you'll get an error):</p>
+
+ <pre class="brush: js">zoomControl: true,
+mapTypeControl: true,
+scaleControl: true,</pre>
+ </li>
+ <li>
+ <p>Now try reloading the example to see the effect these properties have. You can find more options to experiment with at the <a href="https://developers.google.com/maps/documentation/javascript/3.exp/reference#MapOptions">MapOptions object reference page</a>.</p>
+ </li>
+</ol>
+
+<p>That's it for now — have a look around the <a href="https://developers.google.com/maps/documentation/javascript/">Google Maps APIs documentation</a>, and have some more fun playing!</p>
+
+<h2 id="A_RESTful_API_—_NYTimes">A RESTful API — NYTimes</h2>
+
+<p>Now let's look at another API example — the <a href="https://developer.nytimes.com">New York Times API</a>. This API allows you to retrieve New York Times news story information and display it on your site. This type of API is known as a <strong>RESTful API</strong> — instead of getting data using the features of a JavaScript library like we did with Google Maps, we get data by making HTTP requests to specific URLs, with data like search terms and other properties encoded in the URL (often as URL parameters). This is a common pattern you'll encounter with APIs.</p>
+
+<h2 id="An_approach_for_using_third-party_APIs">An approach for using third-party APIs</h2>
+
+<p>Below we'll take you through an exercise to show you how to use the NYTimes API, which also provides a more general set of steps to follow that you can use as an approach for working with new APIs.</p>
+
+<h3 id="Find_the_documentation">Find the documentation</h3>
+
+<p>When you want to use a third party API, it is essential to find out where the documentation is, so you can find out what features the API has, how you use them, etc. The New York Times API documentation is at <a href="https://developer.nytimes.com/">https://developer.nytimes.com/</a>.</p>
+
+<h3 id="Get_a_developer_key">Get a developer key</h3>
+
+<p>Most APIs require you to use some kind of developer key, for reasons of security and accountability. To sign up for an NYTimes API key, you need to go to <a href="https://developer.nytimes.com/signup">https://developer.nytimes.com/signup</a>.</p>
+
+<ol>
+ <li>
+ <p>Let's request a key for the "Article Search API" — fill in the form, selecting this as the API you want to use.</p>
+ </li>
+ <li>
+ <p>Next, wait a few minutes, then get the key from your email.</p>
+ </li>
+ <li>
+ <p>Now, to start the example off, make copies of <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/third-party-apis/nytimes/nytimes_start.html">nytimes_start.html</a> and <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/third-party-apis/nytimes/nytimes.css">nytimes.css</a> in a new directory on your computer. If you've already <a href="/en-US/docs/Learn#Getting_our_code_examples">cloned the examples repository</a>, you'll already have a copy of these files, which you can find in the <em>javascript/apis/third-party-apis/nytimes</em> directory. Initially the <code>&lt;script&gt;</code> element contains a number of variables needed for the setup of the example; below we'll fill in the required functionality.</p>
+ </li>
+</ol>
+
+<p>The app will end up allowing you to type in a search term and optional start and end dates, which it will then use to query the Article Search API and display the search results.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14821/nytimes-search.png" style="border-style: solid; border-width: 1px; display: block; height: 374px; margin: 0px auto; width: 700px;"></p>
+
+<h3 id="Connect_the_API_to_your_app">Connect the API to your app</h3>
+
+<p>First, you'll need to make a connection between the API, and your app. This is usually done either by connecting to the API's JavaScript (as we did in the Google Maps API), or by making requests to the correct URL(s).</p>
+
+<p>In the case of this API, you need to include the API key as a <a href="/en-US/docs/Web/HTTP/Methods/GET">get</a> parameter every time you request data from it.</p>
+
+<ol>
+ <li>
+ <p>Find the following line:</p>
+
+ <pre class="brush: js">var key = 'INSERT-YOUR-API-KEY-HERE';</pre>
+
+ <p>Replace <code>INSERT-YOUR-API-KEY-HERE</code> with the actual API key you got in the previous section.</p>
+ </li>
+ <li>
+ <p>Add the following line to your JavaScript, below the "<code>// Event listeners to control the functionality</code>" comment. This runs a function called <code>fetchResults()</code> when the form is submitted (the button is pressed).</p>
+
+ <pre class="brush: js">searchForm.addEventListener('submit', submitSearch);</pre>
+ </li>
+ <li>
+ <p>Now add the <code>submitSearch()</code> and <code>fetchResults()</code> function definitions, below the previous line:</p>
+
+ <pre class="brush: js">function submitSearch(e) {
+ pageNumber = 0;
+ fetchResults(e);
+}
+
+function fetchResults(e) {
+ // Use preventDefault() to stop the form submitting
+ e.preventDefault();
+
+ // Assemble the full URL
+ url = baseURL + '?api-key=' + key + '&amp;page=' + pageNumber + '&amp;q=' + searchTerm.value <span class="blob-code-inner"><span class="pl-s1"><span class="pl-k x">+</span><span class="x"> </span><span class="pl-s"><span class="pl-pds x">'</span><span class="x">&amp;fq=document_type:("article")</span><span class="pl-pds x x-last">'</span></span></span></span>;
+
+ if(startDate.value !== '') {
+ url += '&amp;begin_date=' + startDate.value;
+ };
+
+ if(endDate.value !== '') {
+ url += '&amp;end_date=' + endDate.value;
+ };
+
+}</pre>
+ </li>
+</ol>
+
+<p><code>submitSearch()</code> sets the page number back to 0 to begin with, then calls <code>fetchResults()</code>. This first calls <code><a href="/en-US/docs/Web/API/Event/preventDefault">preventDefault()</a></code> on the event object, to stop the form actually submitting (which would break the example). Next, we use some string manipulation to assemble the full URL that we will make the request to. We start off by assembling the parts we deem as mandatory for this demo:</p>
+
+<ul>
+ <li>The base URL (taken from the <code>baseURL</code> variable).</li>
+ <li>The API key, which has to be specified in the <code>api-key</code> URL parameter (the value is taken from the <code>key</code> variable).</li>
+ <li>The page number, which has to be specified in the <code>page</code> URL parameter (the value is taken from the <code>pageNumber</code> variable).</li>
+ <li>The search term, which has to be specified in the <code>q</code> URL parameter (the value is taken from the value of the <code>searchTerm</code> text {{htmlelement("input")}}).</li>
+ <li>The document type to return results for, as specified in an expression passed in via the <code>fq</code> URL parameter. In this case, we just want to return articles.</li>
+</ul>
+
+<p>Next, we use a couple of <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/if...else">if()</a></code> statements to check whether the <code>startDate</code> and <code>endDate</code> <code>&lt;input&gt;</code>s have had values filled in on them. If they do, we append their values to the URL, specified in <code>begin_date</code> and <code>end_date</code> URL parameters respectively.</p>
+
+<p>So, a complete URL would end up looking something like this:</p>
+
+<pre>https://api.nytimes.com/svc/search/v2/articlesearch.json?api-key=4f3c267e125943d79b0a3e679f608a78&amp;page=0&amp;q=cats
+&amp;<span class="blob-code-inner"><span class="pl-s1"><span class="pl-s"><span class="x">fq=document_type:("article")</span></span></span></span>&amp;begin_date=20170301&amp;end_date=20170312</pre>
+
+<div class="note">
+<p><strong>Note</strong>: You can find more details of what URL parameters can be included in the <a href="https://developer.nytimes.com/article_search_v2.json">Article Search API reference</a>.</p>
+</div>
+
+<div class="note">
+<p><strong>Note</strong>: The example has rudimentary form data validation — the search term field has to be filled in before the form can be submitted (achieved using the <code>required</code> attribute), and the date fields have <code>pattern</code> attributes specified, which means they won't submit unless their values consist of 8 numbers (<code>pattern="[0-9]{8}"</code>). See <a href="/en-US/docs/Learn/HTML/Forms/Form_validation">Form data validation</a> for more details on how these work.</p>
+</div>
+
+<h3 id="Requesting_data_from_the_API">Requesting data from the API</h3>
+
+<p>Now we've constructed our URL, let's make a request to it. We'll do this using the <a href="/en-US/docs/Web/API/Fetch_API/Using_Fetch">Fetch API</a>.</p>
+
+<p>Add the following code block inside the <code>fetchResults()</code> function, just above the closing curly brace:</p>
+
+<pre class="brush: js">// Use fetch() to make the request to the API
+fetch(url).then(function(result) {
+ return result.json();
+}).then(function(json) {
+ displayResults(json);
+});</pre>
+
+<p>Here we run the request by passing our <code>url</code> variable to <code><a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch">fetch()</a></code>, convert the response body to JSON using the <code><a href="/en-US/docs/Web/API/Body/json">json()</a></code> function, then pass the resulting JSON to the <code>displayResults()</code> function so the data can be displayed in our UI.</p>
+
+<h3 id="Displaying_the_data">Displaying the data</h3>
+
+<p>OK, let's look at how we'll display the data. Add the following function below your <code>fetchResults()</code> function.</p>
+
+<pre class="brush: js">function displayResults(json) {
+ while (section.firstChild) {
+ section.removeChild(section.firstChild);
+ }
+
+ var articles = json.response.docs;
+
+ if(articles.length === 10) {
+ nav.style.display = 'block';
+ } else {
+ nav.style.display = 'none';
+ }
+
+ if(articles.length === 0) {
+ var para = document.createElement('p');
+ para.textContent = 'No results returned.'
+ section.appendChild(para);
+ } else {
+ for(var i = 0; i &lt; articles.length; i++) {
+ var article = document.createElement('article');
+ var heading = document.createElement('h2');
+ var link = document.createElement('a');
+ var img = document.createElement('img');
+ var para1 = document.createElement('p');
+ var para2 = document.createElement('p');
+ var clearfix = document.createElement('div');
+
+ var current = articles[i];
+ console.log(current);
+
+ link.href = current.web_url;
+ link.textContent = current.headline.main;
+ para1.textContent = current.<span class="blob-code-inner"><span class="pl-s1"><span class="pl-smi x x-first x-last">snippet</span></span></span>;
+ para2.textContent = 'Keywords: ';
+ for(var j = 0; j &lt; current.keywords.length; j++) {
+ var span = document.createElement('span');
+ span.textContent += current.keywords[j].value + ' ';
+ para2.appendChild(span);
+ }
+
+ if(current.multimedia.length &gt; 0) {
+ img.src = 'http://www.nytimes.com/' + current.multimedia[0].url;
+ img.alt = current.headline.main;
+ }
+
+ clearfix.setAttribute('class','clearfix');
+
+ article.appendChild(heading);
+ heading.appendChild(link);
+ article.appendChild(img);
+ article.appendChild(para1);
+ article.appendChild(para2);
+ article.appendChild(clearfix);
+ section.appendChild(article);
+ }
+ }
+};</pre>
+
+<p>There's a lot of code here; let's explain it step by step:</p>
+
+<ul>
+ <li>The <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/while">while</a></code> loop is a common pattern used to delete all of the contents of a DOM element, in this case, the {{htmlelement("section")}} element. We keep checking to see if the <code>&lt;section&gt;</code> has a first child, and if it does, we remove the first child. The loop ends when <code>&lt;section&gt;</code> no longer has any children.</li>
+ <li>Next, we set the <code>articles</code> variable to equal <code>json.response.docs</code> — this is the array holding all the objects that represent the articles returned by the search. This is done purely to make the following code a bit simpler.</li>
+ <li>The first <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/if...else">if()</a></code> block checks to see if 10 articles are returned (the API returns up to 10 articles at a time.) If so, we display the {{htmlelement("nav")}} that contains the <em>Previous 10</em>/<em>Next 10</em> pagination buttons. If less than 10 articles are returned, they will all fit on one page, so we don't need to show the pagination buttons. We will wire up the pagination functionality in the next section.</li>
+ <li>The next <code>if()</code> block checks to see if no articles are returned. If so, we don't try to display any — we just create a {{htmlelement("p")}} containing the text "No results returned." and insert it into the <code>&lt;section&gt;</code>.</li>
+ <li>If some articles are returned, we, first of all, create all the elements that we want to use to display each news story, insert the right contents into each one, and then insert them into the DOM at the appropriate places. To work out which properties in the article objects contained the right data to show, we consulted the <a href="https://developer.nytimes.com/article_search_v2.json">Article Search API reference</a>. Most of these operations are fairly obvious, but a few are worth calling out:
+ <ul>
+ <li>We used a <a href="/en-US/docs/Web/JavaScript/Reference/Statements/for">for loop</a> (<code>for(var j = 0; j &lt; current.keywords.length; j++) { ... }</code> ) to loop through all the keywords associated with each article, and insert each one inside its own {{htmlelement("span")}}, inside a <code>&lt;p&gt;</code>. This was done to make it easy to style each one.</li>
+ <li>We used an <code>if()</code> block (<code>if(current.multimedia.length &gt; 0) { ... }</code>) to check whether each article actually has any images associated with it (some stories don't.) We display the first image only if it actually exists (otherwise an error would be thrown).</li>
+ <li>We gave our &lt;div&gt; element a class of "clearfix", so we can easily apply clearing to it (this technique is needed at the time of writing to stop floated layouts from breaking.)</li>
+ </ul>
+ </li>
+</ul>
+
+<p>If you try the example now, it should work, although the pagination buttons won't work yet.</p>
+
+<h3 id="Wiring_up_the_pagination_buttons">Wiring up the pagination buttons</h3>
+
+<p>To make the pagination buttons work, we will increment (or decrement) the value of the <code>pageNumber</code> variable, and then re-rerun the fetch request with the new value included in the page URL parameter. This works because the NYTimes API only returns 10 results at a time — if more than 10 results are available, it will return the first 10 (0-9) if the <code>page</code> URL parameter is set to 0 (or not included at all — 0 is the default value), the next 10 (10-19) if it is set to 1, and so on.</p>
+
+<p>This allows us to easily write a simplistic pagination function.</p>
+
+<ol>
+ <li>
+ <p>Below the existing <code><a href="/en-US/docs/Web/API/EventTarget/addEventListener">addEventListener()</a></code> call, add these two new ones, which cause the <code>nextPage()</code> and <code>previousPage()</code> functions to be invoked when the relevant buttons are clicked:</p>
+
+ <pre class="brush: js">nextBtn.addEventListener('click', nextPage);
+previousBtn.addEventListener('click', previousPage);</pre>
+ </li>
+ <li>
+ <p>Below your previous addition, let's define the two functions — add this code now:</p>
+
+ <pre class="brush: js">function nextPage(e) {
+ pageNumber++;
+ fetchResults(e);
+};
+
+function previousPage(e) {
+ if(pageNumber &gt; 0) {
+ pageNumber--;
+ } else {
+ return;
+ }
+ fetchResults(e);
+};</pre>
+
+ <p>The first function is simple — we increment the <code>pageNumber</code> variable, then run the <code>fetchResults()</code> function again to display the next page's results.</p>
+
+ <p>The second function works nearly exactly the same way in reverse, but we also have to take the extra step of checking that <code>pageNumber</code> is not already zero before decrementing it — if the fetch request runs with a minus <code>page</code> URL parameter, it could cause errors. If the <code>pageNumber</code> is already 0, we simply <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/return">return</a></code> out of the function, to avoid wasting processing power (If we are already at the first page, we don't need to load the same results again).</p>
+ </li>
+</ol>
+
+<h2 id="YouTube_example">YouTube example</h2>
+
+<p>We also built another example for you to study and learn from — see our <a href="https://mdn.github.io/learning-area/javascript/apis/third-party-apis/youtube/">YouTube video search example</a>. This uses two related APIs:</p>
+
+<ul>
+ <li>The <a href="https://developers.google.com/youtube/v3/docs/">YouTube Data API</a> to search for YouTube videos and return results.</li>
+ <li>The <a href="https://developers.google.com/youtube/iframe_api_reference">YouTube IFrame Player API</a> to display the returned video examples inside IFrame video players so you can watch them.</li>
+</ul>
+
+<p>This example is interesting because it shows two related third-party APIs being used together to build an app. The first one is a RESTful API, while the second one works more like Google Maps (with constructors, etc.). It is worth noting however that both of the APIs require a JavaScript library to be applied to the page. The RESTful API has functions available to handle making the HTTP requests and returning the results, so you don't have to write them out yourself using say fetch or XHR.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14823/youtube-example.png" style="border-style: solid; border-width: 1px; display: block; height: 389px; margin: 0px auto; width: 700px;"></p>
+
+<p>We are not going to say too much more about this example in the article — <a href="https://github.com/mdn/learning-area/tree/master/javascript/apis/third-party-apis/youtube">the source code</a> has detailed comments inserted inside it to explain how it works.</p>
+
+<h2 id="Summary">Summary</h2>
+
+<p>This article has given you a useful introduction to using third party APIs to add functionality to your websites.</p>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Client-side_web_APIs/Fetching_data", "Learn/JavaScript/Client-side_web_APIs/Drawing_graphics", "Learn/JavaScript/Client-side_web_APIs")}}</p>
+
+<p> </p>
+
+<h2 id="In_this_module">In this module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Introduction">Introduction to web APIs</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Manipulating_documents">Manipulating documents</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Fetching_data">Fetching data from the server</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Third_party_APIs">Third party APIs</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Drawing_graphics">Drawing graphics</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Video_and_audio_APIs">Video and audio APIs</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Client-side_storage">Client-side storage</a></li>
+</ul>
diff --git a/files/ru/learn/javascript/howto/index.html b/files/ru/learn/javascript/howto/index.html
new file mode 100644
index 0000000000..b3fa76b1cf
--- /dev/null
+++ b/files/ru/learn/javascript/howto/index.html
@@ -0,0 +1,304 @@
+---
+title: Решите общие проблемы в вашем JavaScript-коде
+slug: Learn/JavaScript/Howto
+tags:
+ - Начинающий
+translation_of: Learn/JavaScript/Howto
+---
+<div>{{LearnSidebar}}</div>
+
+<p class="summary">Следующие ссылки указывают на решение общих повседневных проблем, которые вам нужно будет исправить, чтобы код  JavaScript  работал правильно.</p>
+
+<h2 id="Частые_ошибки_начинающих">Частые ошибки начинающих</h2>
+
+<h3 id="Правильное_написание_и_оболочка">Правильное написание и оболочка</h3>
+
+<p> </p>
+
+<p>Если ваш код не работает и / или браузер жалуется, что что-то не определено, убедитесь, что вы правильно указали все имена переменных, имена функций и т. д.</p>
+
+<p>Некоторые общие встроенные функции браузера, которые вызывают проблемы:</p>
+
+<p> </p>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">Correct</th>
+ <th scope="col">Wrong</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><code>getElementsByTagName()</code></td>
+ <td><code>getElementbyTagName()</code></td>
+ </tr>
+ <tr>
+ <td><code>getElementsByName()</code></td>
+ <td><code>getElementByName()</code></td>
+ </tr>
+ <tr>
+ <td><code>getElementsByClassName()</code></td>
+ <td><code>getElementByClassName()</code></td>
+ </tr>
+ <tr>
+ <td><code>getElementById()</code></td>
+ <td><code>getElementsById()</code></td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id="Положение_двоеточия_точки_с_запятой">Положение двоеточия / точки с запятой</h3>
+
+<p>Вам нужно убедиться, что вы не помещаете точки с запятой неправильно. Например:</p>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">Correct</th>
+ <th scope="col">Wrong</th>
+ </tr>
+ <tr>
+ <td><code>elem.style.color = 'red';</code></td>
+ <td><code>elem.style.color = 'red;'</code></td>
+ </tr>
+ </thead>
+</table>
+
+<h3 id="Функции">Функции</h3>
+
+<p> </p>
+
+<p>Есть ряд вещей, которые могут пойти не так с функциями.</p>
+
+<p>Одна из наиболее распространенных ошибок - объявить функцию, но не называть ее нигде. Например</p>
+
+<p>:</p>
+
+<pre class="brush: js">function myFunction() {
+ alert('This is my function.');
+};</pre>
+
+<p>Этот код ничего не сделает, если вы его не назовете, например</p>
+
+<pre class="brush: js">myFunction();</pre>
+
+<h4 id="Область_действия">Область действия</h4>
+
+<p>Помнините, что <a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions#Function_scope_and_conflicts">functions have their own scope</a> —вы не можете получить доступ к значению переменной, установленному внутри функции извне функции, если вы не объявили переменную глобально (т. е. не внутри каких-либо функций), или <a href="/en-US/docs/Learn/JavaScript/Building_blocks/Return_values">return the value</a> из функции.</p>
+
+<h4 id="Запуск_кода_после_оператора_возврата">Запуск кода после оператора возврата</h4>
+
+<p> </p>
+
+<p>Помните также, что когда вы возвращаете значение из функции, интерпретатор JavaScript выходит из функции - никакой код  после выполнения оператора return не выполняется.</p>
+
+<p>Фактически, некоторые браузеры (например, Firefox) выдадут вам сообщение об ошибке в консоли разработчика, если у вас есть код после оператора return. Firefox дает вам «недостижимый код после оператора возврата».</p>
+
+<p> </p>
+
+<h3 id="Обозначение_объекта_по_сравнению_с_обычным_назначением">Обозначение объекта по сравнению с обычным назначением</h3>
+
+<p>Когда вы назначаете что-то в JavaScript, вы используете один знак равенства, например:</p>
+
+<pre class="brush: js">var myNumber = 0;</pre>
+
+<p>Это не работает в <a href="/en-US/docs/Learn/JavaScript/Objects">Objects</a>, однако - с объектами, вам нужно отделить имена членов от их значений, используя двоеточия, и разделить каждый элемент запятой, например:</p>
+
+<pre class="brush: js">var myObject = {
+ name : 'Chris',
+ age : 38
+}</pre>
+
+<h2 id="Basic_definitions">Basic definitions</h2>
+
+<div class="column-container">
+<div class="column-half">
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/What_is_JavaScript#A_high-level_definition">What is JavaScript?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Variables#What_is_a_variable">What is a variable?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Strings">What are strings?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Arrays#What_is_an_Array">What is an array?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code">What is a loop?</a></li>
+</ul>
+</div>
+
+<div class="column-half">
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions">What is a function?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events">What is an event?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics#Object_basics">What is an object?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/JSON#No_really_what_is_JSON">What is JSON?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Introduction#What_are_APIs">What is a web API?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Manipulating_documents#The_document_object_model">What is the DOM?</a></li>
+</ul>
+</div>
+</div>
+
+<h2 id="Basic_use_cases">Basic use cases</h2>
+
+<div class="column-container">
+<div class="column-half">
+<h3 id="General">General</h3>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/What_is_JavaScript#How_do_you_add_JavaScript_to_your_page">How do you add JavaScript to your page?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/What_is_JavaScript#Comments">How do you add comments to JavaScript code?</a></li>
+</ul>
+
+<h3 id="Variables">Variables</h3>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Variables#Declaring_a_variable">How do you declare a variable?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Variables#Initializing_a_variable">How do you initialize a variable with a value?</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/Variables#Updating_a_variable">How do you update a variable's value?</a> (also see <a href="/en-US/docs/Learn/JavaScript/First_steps/Math#Assignment_operators">Assignment operators</a>)</li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/Variables#Variable_types">What data types can values have in JavaScript?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Variables#Loose_typing">What does 'loosely typed' mean?</a></li>
+</ul>
+
+<h3 id="Math">Math</h3>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Math#Types_of_numbers">What types of number do you have to deal with in web development?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Math#Arithmetic_operators">How do you do basic math in JavaScript?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Math#Operator_precedence">What is operator precedence, and how is it handled in JavaScript?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Math#Increment_and_decrement_operators">How do you increment and decrement values in JavaScript?</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/Math#Comparison_operators">How do you compare values in JavaScript?</a> (e.g. to see which one is bigger, or to see if one value is equal to another).</li>
+</ul>
+
+<h3 id="Strings">Strings</h3>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Strings#Creating_a_string">How do you create a string in JavaScript?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Strings#Single_quotes_versus_double_quotes">Do you have to use single quotes or double quotes?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Strings#Escaping_characters_in_a_string">How do you escape characters in strings?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Strings#Concatenating_strings">How do you join strings together?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Strings#Numbers_versus_strings">Can you join strings and numbers together?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Useful_string_methods#Finding_the_length_of_a_string">How do you find the length of a string?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Useful_string_methods#Retrieving_a_specific_string_character">How you find what character is at a certain position in a string?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Useful_string_methods#Finding_a_substring_inside_a_string_and_extracting_it">How do you find and extract a specific substring from a string?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Useful_string_methods#Changing_case">How do you change the case of a string?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Useful_string_methods#Updating_parts_of_a_string">How do you replace one specific substring with another?</a></li>
+</ul>
+</div>
+
+<div class="column-half">
+<h3 id="Arrays">Arrays</h3>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Arrays#Creating_an_array">How do you create an array?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Arrays#Accessing_and_modifying_array_items">How do you access and modify the items in an array?</a> (this includes multidimensional arrays)</li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Arrays#Finding_the_length_of_an_array">How do you find the length of an array?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Arrays#Adding_and_removing_array_items">How you add and remove array items?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Arrays#Converting_between_strings_and_arrays">How do you split a string into array items, or join array items into a string?</a></li>
+</ul>
+
+<h3 id="Debugging_JavaScript">Debugging JavaScript</h3>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/What_went_wrong#Types_of_error">What are the basic types of error?</a></li>
+ <li><a href="/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools">What are browser developer tools, and how do you access them?</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/JavaScript#The_Console_API">How do you log a value to the JavaScript console?</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/JavaScript#Using_the_JavaScript_debugger">How do you use breakpoints, and other JavaScript debugging features?</a></li>
+</ul>
+
+<p>For more information on JavaScript debugging, see <a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/JavaScript">Handling common JavaScript problems</a>; also see <a href="/en-US/docs/Learn/JavaScript/First_steps/What_went_wrong#Other_common_errors">Other common errors</a> for a description of common errors.</p>
+
+<h3 id="Making_decisions_in_code">Making decisions in code</h3>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/conditionals">How do you execute different blocks of code, depending on a variable's value or other condition?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/conditionals#if_..._else_statements">How do you use if ...else statements?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/conditionals#Nesting_if_..._else">How do nest one decision block inside another?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/conditionals#Logical_operators_AND_OR_and_NOT">How do you use AND, OR, and NOT operators in JavaScript?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/conditionals#switch_statements">How do you conveniently handle a large number of choices for one condition?</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/conditionals#Ternary_operator">How do you use a ternary operator to make a quick choice between two options based on a true or false test?</a></li>
+</ul>
+
+<h3 id="Loopingiteration">Looping/iteration</h3>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code">How do you run the same bit of code over and over again?</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code#Exiting_loops_with_break">How do you exit a loop before the end if a certain condition is met?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code#Skipping_iterations_with_continue">How do you skip to the next iteration of a loop if a certain condition is met?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code#while_and_do_..._while">How do you use while and do ... while loops?</a></li>
+ <li>How to iterate over the elements in an array</li>
+ <li>How to iterate over the elements in a multidimensional array</li>
+ <li>How to iterate over the members in an object</li>
+ <li>How to iterate over the members of an object nested inside an array</li>
+</ul>
+</div>
+</div>
+
+<h2 id="Intermediate_use_cases">Intermediate use cases</h2>
+
+<div class="column-container">
+<div class="column-half">
+<h3 id="Functions">Functions</h3>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions#Built-in_browser_functions">How do you find functions in the browser?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions#Functions_versus_methods">What is the difference between a function and a method?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">How do you create your own functions?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions#Invoking_functions">How do you run (call, or invoke) a function?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions#Anonymous_functions">What is an anonymous function?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions#Function_parameters">How do you specify parameters (or arguments) when invoking a function?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions#Function_scope_and_conflicts">What is function scope?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Return_values">What are return values, and how do you use them?</a></li>
+</ul>
+
+<h3 id="Objects">Objects</h3>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics#Object_basics">How do you create an object?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics#Dot_notation">What is dot notation?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics#Bracket_notation">What is bracket notation?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics#Setting_object_members">How do you get and set the methods and properties of an object?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics#What_is_this">What is <code>this</code>, in the context of an object?</a></li>
+ <li><a href="/docs/Learn/JavaScript/Objects/Object-oriented_JS#Object-oriented_programming_from_10000_meters">What is object-oriented programming?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS#Constructors_and_object_instances">What are constructors and instances, and how do you create them?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS#Other_ways_to_create_object_instances">What different ways are there to create objects in JavaScript?</a></li>
+</ul>
+
+<h3 id="JSON">JSON</h3>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/JSON#JSON_structure">How do you structure JSON data, and read it from JavaScript?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/JSON#Loading_our_JSON">How can you load a JSON file into a page?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/JSON#Converting_between_objects_and_text">How do you convert a JSON object to a text string, and back again?</a></li>
+</ul>
+</div>
+
+<div class="column-half">
+<h3 id="Events">Events</h3>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events#Event_handler_properties">What are event handlers and how do you use them?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events#Inline_event_handlers_%E2%80%94_don%27t_use_these">What are inline event handlers?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events#addEventListener()_and_removeEventListener()">What does the <code>addEventListener()</code> function do, and how do you use it?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events#What_mechanism_should_I_use">Which mechanism should I use to add event code to my web pages?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events#Event_objects">What are event objects, and how do you use them?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events#Preventing_default_behaviour">How do you prevent default event behaviour?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events#Event_bubbling_and_capture">How do events fire on nested elements? (event propagation, also related — event bubbling and capturing)</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events#Event_delegation">What is event delegation, and how does it work?</a></li>
+</ul>
+
+<h3 id="Object-oriented_JavaScript">Object-oriented JavaScript</h3>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_prototypes">What are object prototypes?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_prototypes#The_constructor_property">What is the constructor property, and how can you use it?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_prototypes#Modifying_prototypes">How do you add methods to the constructor?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Inheritance">How do you create a new constructor that inherits its members from a parent constructor?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Inheritance#Object_member_summary">When should you use inheritance in JavaScript?</a></li>
+</ul>
+
+<h3 id="Web_APIs">Web APIs</h3>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Manipulating_documents#Active_learning_Basic_DOM_manipulation">How do you manipulate the DOM (e.g. adding or removing elements) using JavaScript?</a></li>
+</ul>
+
+<p> </p>
+</div>
+</div>
diff --git a/files/ru/learn/javascript/index.html b/files/ru/learn/javascript/index.html
new file mode 100644
index 0000000000..586c33a969
--- /dev/null
+++ b/files/ru/learn/javascript/index.html
@@ -0,0 +1,64 @@
+---
+title: JavaScript
+slug: Learn/JavaScript
+tags:
+ - JavaScript
+ - Начала
+ - Начинающий
+ - Основы
+translation_of: Learn/JavaScript
+---
+<div>{{LearnSidebar}}</div>
+
+<p class="summary">{{Glossary("JavaScript")}} — это язык программирования, который даёт возможность реализовывать сложное поведение веб-страницы. Каждый раз, когда вы видите веб-страницу, она не только отображает статическое содержимое, но и делает большее - своевременно отображает обновление контента, выводит интерактивные карты, 2D/3D анимацию, прокручивает видео и т.д. - будьте уверены, здесь не обошлось без JavaScript.</p>
+
+<h2 id="Учебный_план">Учебный план</h2>
+
+<p>Считается, что JavaScript сложнее изучить, чем связанные с ним технологии, наподобие <a href="/ru/docs/Learn/HTML">HTML</a> и <a href="/ru/docs/Learn/CSS">CSS</a>. Поэтому, перед изучением JavaScript, настоятельно рекомендуем сначала ознакомиться хотя бы с этими двумя технологиями. Начните с проработки следующих модулей:</p>
+
+<ul>
+ <li><a href="/ru/docs/Learn/Getting_started_with_the_web">Начало работы с Веб</a></li>
+ <li><a href="/ru/docs/Web/Guide/HTML/Introduction">Введение в HTML</a></li>
+ <li><a href="/ru/docs/Learn/CSS/First_steps">Введение в CSS</a></li>
+</ul>
+
+<p>Имеющийся опыт программирования на других языках также может помочь в обучении.</p>
+
+<p>После изучения основ JavaScript вы будете готовы к ознакомлению с более сложными темами, например:</p>
+
+<ul>
+ <li>Углубленный курс JavaScript, изложенный в нашем <a href="/ru/docs/Web/JavaScript/Guide">Руководстве по JavaScript</a></li>
+ <li><a href="/ru/docs/Web/API">Программный интерфейс WebAPI</a></li>
+</ul>
+
+<h2 id="Модули">Модули</h2>
+
+<p>Этот раздел содержит следующие модули, проходить которые рекомендуется в порядке перечисления.</p>
+
+<dl>
+ <dt><a href="/ru/docs/Learn/JavaScript/Первые_шаги">Первые шаги в JavaScript</a></dt>
+ <dd>В нашем первом модуле, посвященном JavaScript, мы сначала ответим на несколько главных вопросов, таких, как "Что такое JavaScript?",  "На что он похож?" и "Что с его помощью можно сделать?", а затем перейдем к практике - расскажем, как писать и выполнять код на JavaScript. После чего подробнее рассмотрим некоторые ключевые конструкции JavaScript: переменные, строки, числа и массивы.</dd>
+ <dt><a href="/ru/docs/Learn/JavaScript/Building_blocks">Структурные элементы JavaScript</a></dt>
+ <dd>В этом модуле мы продолжим изучение главных составных частей JavaScript и обратим внимание на повсеместно встречающиеся типы конструкций: условные операторы, циклы, функции и события. В ходе обучения Вы уже сталкивались с ними, но только мимоходом. Теперь мы поговорим именно о них.</dd>
+ <dt><a href="/ru/docs/Learn/JavaScript/Объекты">Введение в объекты JavaScript</a></dt>
+ <dd>Практически всё, что встречается в JavaScript, является объектом. Начиная с таких ключевых конструкций, как строки и массивы, и заканчивая интерфейсом взаимодействия с браузером, который построен поверх JavaScript. Вы даже можете создавать собственные объекты, заключая взаимосвязанные функции и переменные в готовые пакеты. Если Вы хотите продолжить изучение языка и писать более эффективный код, то очень важно понять объектно-ориентированную природу JavaScript. Чтобы помочь Вам в этом, мы представляем этот модуль. В нем мы подробно рассматриваем основы и синтаксис ООП (объектно-ориентированного программирования), показываем, как создавать свои объекты, и объясняем, что такое данные в формате JSON и как с ними работать.</dd>
+ <dt><a href="/ru/docs/Learn/JavaScript/Client-side_web_APIs">Клиентский Web API</a></dt>
+ <dd>При написании клиентского JavaScript для сайтов или приложений вы не обойдётесь без использования API - то есть интерфейсов для работы с различными функциями браузера или операционной системы, на которой работает сайт, или даже для работы с данными, получаемыми с других сайтов или сервисов. В этом модуле мы изучим, какие это API и как использовать некоторые наиболее распространённые API, которые вам будут часто попадаться во время разработки.</dd>
+</dl>
+
+<h2 id="Решение_общих_проблем_на_JavaScript">Решение общих проблем на JavaScript</h2>
+
+<p>Статья <a href="/ru/docs/Learn/JavaScript/Howto">Использование JavaScript для решения общих проблем</a> предоставляет ссылки к секциям контента, раскрывающих суть того, как использовать JavaScript для решения очень часто встречающихся проблем при создании веб-страницы.</p>
+
+<h2 id="Смотрите_также">Смотрите также</h2>
+
+<dl>
+ <dt><a href="/ru/docs/Web/JavaScript">JavaScript на MDN</a></dt>
+ <dd>Главная точка входа к ядру JavaScript-документации на MDN — то место, где вы найдёте обширную справочную документация по всем аспектам языка JavaScript, и некоторые продвинутые учебники для опытных JavaScript-разработчиков.</dd>
+ <dt><a href="https://learnjavascript.online">Learn JavaScript</a></dt>
+ <dd>Отличный ресурс для начинающих веб-разработчиков - изучайте JavaScript в интерактивной среде, с короткими уроками и интерактивными тестами с автоматизированной оценкой. Первые 40 уроков бесплатно, а полный курс доступен за небольшую разовую плату.</dd>
+ <dt><a href="https://exlskills.com/learn-en/courses/javascript-fundamentals-basics_javascript">JavaScript Fundamentals на EXLskills</a></dt>
+ <dd>Изучайте JavaScript бесплатно с курсом с открытым исходным кодом EXLskills, который знакомит вас со всем необходимым, чтобы начать создавать приложения в JS.</dd>
+ <dt><a href="https://www.youtube.com/user/codingmath">Математика для программиста</a></dt>
+ <dd>Великолепная серия видеоуроков по математике от <a href="https://twitter.com/bit101">Keith Peters</a>, которую необходимо понимать каждому эффективному программисту</dd>
+</dl>
diff --git a/files/ru/learn/javascript/объекты/adding_bouncing_balls_features/index.html b/files/ru/learn/javascript/объекты/adding_bouncing_balls_features/index.html
new file mode 100644
index 0000000000..fe97392371
--- /dev/null
+++ b/files/ru/learn/javascript/объекты/adding_bouncing_balls_features/index.html
@@ -0,0 +1,212 @@
+---
+title: Добавление функций в нашу демонстрацию отбойных шаров
+slug: Learn/JavaScript/Объекты/Adding_bouncing_balls_features
+translation_of: Learn/JavaScript/Objects/Adding_bouncing_balls_features
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Objects/Object_building_practice", "", "Learn/JavaScript/Objects")}}</div>
+
+<p class="summary">В этом упражнении мы будем использовать проект прыгающих шаров из предыдущей статьи и добавим в него новые интересные возможности.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Требования:</th>
+ <td>Перед тем как приступить к этому упражнению нужно выполнить задания из всех статей текущего модуля.</td>
+ </tr>
+ <tr>
+ <th scope="row">Цель:</th>
+ <td>Проверить насколько хорошо вы понимаете объекты и связанные с ними конструкции в языке Javascript. </td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Начало">Начало</h2>
+
+<p>Для начала скопируйте файлы <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/index-finished.html">index-finished.html</a>, <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/style.css">style.css</a> и <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/main-finished.js">main-finished.js</a> из предыдущей статьи в новую директорию на вашем компьютере.</p>
+
+<p>Для выполнения упражнения вы можете использовать сайт <a class="external external-icon" href="http://jsbin.com/">JSBin</a> или <a class="external external-icon" href="https://thimble.mozilla.org/">Thimble</a>. Вы можете вставлять HTML, CSS и JavaScript код в один из этих онлайн-редакторов. Если ваш онлайн-редактор не поддерживает раздельные панели для редактирования JavaScript/CSS кода, то вы можете встроить код в HTML с помощью тегов <code>&lt;script&gt;</code>/<code>&lt;style&gt;</code>.</p>
+
+<div class="note">
+<p><strong>Примечание</strong>. Если у вас что-то не получается — попросите о помощи. Более подробная информация находится в секции {{anch("Assessment or further help")}} в конце этой страницы.</p>
+</div>
+
+<h2 id="Краткое_описание_проекта">Краткое описание проекта</h2>
+
+<p>Наша веселая демонстрация шаров - это весело, но теперь мы хотим сделать ее немного более интерактивной, добавив контролируемый пользователем злой круг, который будет есть шары, если он их поймает. Мы также хотим проверить ваши навыки создания объектов, создав общий объект <code>Shape()</code>, который могут наследовать наши шары и злой круг. Наконец, мы хотим добавить счетчик очков, чтобы отслеживать количество оставшихся шаров для захвата.</p>
+
+<p>Следующий скриншот дает вам представление о том, как должна выглядеть готовая программа:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13875/bouncing-evil-circle.png" style="display: block; margin: 0 auto;"></p>
+
+<ul>
+</ul>
+
+<p>Чтобы дать вам больше идеи, посмотрите на <a href="https://mdn.github.io/learning-area/javascript/oojs/assessment/">законченный пример</a> (не заглядывая в исходный код!)</p>
+
+<h2 id="Шаги_по_завершению">Шаги по завершению</h2>
+
+<p>В следующих разделах описывается, что вам нужно делать.</p>
+
+<h3 id="Создание_наших_новых_объектов">Создание наших новых объектов</h3>
+
+<p>Прежде всего, измените существующий конструктор <code>Ball()</code> так, чтобы он стал конструктором <code>Shape()</code> и добавил новый конструктор <code>Ball()</code>:</p>
+
+<ol>
+ <li>Конструктор <code>Shape()</code> должен определять свойства <code>x</code>, <code>y</code>, <code>velX</code> и <code>velY</code>,  так же, как и конструктор <code>Ball()</code>, но не свойства <code>color</code> и <code>size</code>.</li>
+ <li>Он также должен определить новое свойство<code>exists</code>, которое используется для отслеживания наличия шаров в программе (не было съедено злым кругом). Это должно быть логическое (<code>true</code> / <code>false</code>).</li>
+ <li>Конструктор <code>Ball()</code> должен наследовать свойства <code>x</code>, <code>y</code>, <code>velX</code>, <code>velY</code> и <code>exists</code> из конструктора <code>Shape()</code>.</li>
+ <li>Он также должен определить свойство <code>color</code> и <code>size</code>, как это сделал оригинальный конструктор <code>Ball()</code>.</li>
+ <li>Не забудьте установить <code>prototype</code> и <code>constructor</code> конструктора <code>Ball()</code> соответствующим образом.</li>
+</ol>
+
+<p>Определения меток шара <code>draw()</code>, <code>update()</code> и <code>collisionDetect()</code> должны быть такими же, как и раньше.</p>
+
+<p>Вам также нужно добавить новый параметр в новый вызов конструктора <code>new Ball() ( ... )</code> - параметр <code>exists</code> должен быть 5-м параметром и ему должно быть присвоено значение <code>true</code>.</p>
+
+<p>На этом этапе попробуйте перезагрузить код - он должен работать так же, как и раньше, с нашими перепроектированными объектами.</p>
+
+<h3 id="Определение_EvilCircle">Определение EvilCircle()</h3>
+
+<p>Теперь пришло время встретить плохого парня - <code>EvilCircle()</code>! Наша игра будет включать только один злой круг, но мы все еще будем определять его с помощью конструктора, который наследует от <code>Shape()</code>, чтобы дать вам некоторую практику. Возможно, вам захочется добавить еще один круг в приложение, которое может контролироваться другим игроком или иметь несколько злобных окружений, управляемых компьютером. Вы, вероятно, не собираетесь захватить мир одним злым кругом, но он будет делать для этой оценки.</p>
+
+<p>Конструктор <code>EvilCircle()</code> должен наследовать <code>x</code>, <code>y</code>, <code>velX</code>, <code>velY</code> и <code>exists</code> из <code>Shape()</code>, но <code>velX</code> и <code>velY</code> должны всегда равняться 20.</p>
+
+<p>Вы должны сделать что-то вроде <code>Shape.call(this, x, y, 20, 20, exists);</code></p>
+
+<p>Он также должен определить свои собственные свойства следующим образом:</p>
+
+<ul>
+ <li><code>color</code> — <code>'white'</code></li>
+ <li><code>size</code> — <code>10</code></li>
+</ul>
+
+<p>Опять же, не забудьте определить свои унаследованные свойства как параметры в конструкторе и правильно установить свойства <code>prototype</code> и <code>constructor</code>.</p>
+
+<h3 id="Defining_EvilCircles_methods">Defining EvilCircle()'s methods</h3>
+
+<p><code>EvilCircle()</code> должен иметь четыре метода, как описано ниже.</p>
+
+<h4 id="draw"><code>draw()</code></h4>
+
+<p>Этот метод имеет ту же цель, что и метод <code>draw()</code> метода <code>Ball()</code>: он рисует экземпляр объекта на холсте. Он будет работать очень схожим образом, поэтому вы можете начать с копирования определения <code>Ball.prototype.draw</code>. Затем вы должны внести следующие изменения:</p>
+
+<ul>
+ <li>Мы хотим, чтобы злой круг не был заполнен, а скорее имел внешнюю линию (удар). Вы можете добиться этого, обновив <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle">fillStyle</a></code> и <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fill">fill()</a></code> до <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/strokeStyle">strokeStyle</a></code> и s<code><a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/stroke">stroke()</a></code>.</li>
+ <li>Мы также хотим сделать ход немного толще, так что вы можете увидеть злой круг немного легче. Этого можно добиться, установив значение для <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineWidth">lineWidth</a></code> где-нибудь после вызова <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/beginPath">beginPath()</a></code> (3 будем делать).</li>
+</ul>
+
+<h4 id="checkBounds"><code>checkBounds()</code></h4>
+
+<p>Этот метод будет делать то же самое, что и первая часть функции  <code>Ball()</code>'s <code>update()</code>, чтобы посмотреть, не исчезнет ли злой круг от края экрана и не прекратит это делать. Опять же, вы можете просто скопировать определение <code>Ball.prototype.update</code>, но есть несколько изменений, которые вы должны сделать:</p>
+
+<ul>
+ <li>Избавьтесь от последних двух строк - мы не хотим автоматически обновлять позицию злого круга на каждом кадре, потому что мы будем перемещать его каким-то другим способом, как вы увидите ниже.</li>
+ <li>Внутри операторов <code>if()</code>, если тесты возвращают true, мы не хотим обновлять <code>velX</code> / <code>velY</code>; мы хотим вместо этого изменить значение <code>x</code> / <code>y</code>, так что злой круг возвращается на экран немного. Добавление или вычитание (по мере необходимости) свойства <code>size</code> злого круга имеет смысл.</li>
+</ul>
+
+<h4 id="setControls"><code>setControls()</code></h4>
+
+<p>Этот метод добавит прослушиватель событий <code>onkeydown</code> к объекту <code>window</code>, чтобы при нажатии определенных клавиш клавиатуры мы могли перемещать злой круг вокруг. Следующий код должен быть помещен внутри определения метода:</p>
+
+<pre class="brush: js">var _this = this;
+window.onkeydown = function(e) {
+ if (e.keyCode === 65) {
+ _this.x -= _this.velX;
+ } else if (e.keyCode === 68) {
+ _this.x += _this.velX;
+ } else if (e.keyCode === 87) {
+ _this.y -= _this.velY;
+ } else if (e.keyCode === 83) {
+ _this.y += _this.velY;
+ }
+ }</pre>
+
+<p>Поэтому, когда нажата клавиша, проконсультируется о свойствах <a href="https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode">keyCode</a> объекта события, чтобы увидеть, какая клавиша нажата. Если это один из четырех, представленных указанными ключевыми кодами, тогда злой круг будет перемещаться влево / вправо / вверх / вниз.</p>
+
+<ul>
+ <li>Для бонусного пункта сообщите нам, к каким ключам относятся указанные коды ключей.</li>
+ <li>В другой бонусной точке вы можете сказать нам, почему нам пришлось установить <code>var _this = this</code>; в позиции, в которой он находится? Это как-то связано с функциональной областью.</li>
+</ul>
+
+<h4 id="collisionDetect"><code>collisionDetect()</code></h4>
+
+<p>Этот метод будет действовать очень похоже на метод <code>collisionDetect()</code> в <code>Ball()</code>, поэтому вы можете использовать его в качестве основы для этого нового метода. Но есть несколько отличий:</p>
+
+<ul>
+ <li>В внешнем выражении <code>if</code> вам больше не нужно проверять, совпадает ли текущий мяч на итерации с шаром, который выполняет проверку, потому что он больше не является мячиком, это злой круг! Вместо этого вам нужно выполнить проверку, чтобы проверить, существует ли проверенный шар (с каким свойством вы могли бы это сделать?). Если этого не существует, он уже был съеден злым кругом, поэтому нет необходимости проверять его снова.</li>
+ <li>Во внутреннем <code>if</code>-выражении вы больше не хотите, чтобы объекты меняли цвет при обнаружении столкновения - вместо этого вы хотите установить любые шары, которые сталкиваются с злым кругом, чтобы больше не существовать (опять же, как вы думаете, d сделать это?).</li>
+</ul>
+
+<h3 id="Приведение_злого_круга_в_программу">Приведение злого круга в программу</h3>
+
+<p>Теперь мы определили злой круг, нам нужно на самом деле заставить его появиться на нашей сцене. Для этого вам нужно внести некоторые изменения в функцию <code>loop()</code>.</p>
+
+<ul>
+ <li>Прежде всего, создайте новый экземпляр объекта злого круга (указав необходимые параметры), затем вызовите его метод <code>setControls()</code>. Вам нужно только сделать эти две вещи один раз, а не на каждой итерации цикла.</li>
+ <li>В точке, где вы прокручиваете каждый шар и вызываете функции <code>draw()</code>, <code>update()</code> и <code>collisionDetect()</code> для каждого из них, делайте так, чтобы эти функции вызывались только в том случае, если текущий шар существует.</li>
+ <li>На каждой итерации цикла вызовите методы draw <code>draw()</code>, <code>checkBounds()</code> и <code>collisionDetect()</code> для злого шарика.</li>
+</ul>
+
+<h3 id="Реализация_счетчика_баллов">Реализация счетчика баллов</h3>
+
+<p>Чтобы выполнить счетчик счетчиков, выполните следующие действия:</p>
+
+<ol>
+ <li>В своем HTML-файле добавьте элемент {{HTMLElement ("p")}} непосредственно под элементом {{HTMLElement ("h1")}}, содержащим текст «Ball count:».</li>
+ <li>В вашем файле CSS добавьте следующее правило внизу:
+ <pre class="brush: css">p {
+ position: absolute;
+ margin: 0;
+ top: 35px;
+ right: 5px;
+ color: #aaa;
+}</pre>
+ </li>
+ <li>В своем JavaScript сделайте следующие обновления:
+ <ul>
+ <li>Создайте переменную, которая хранит ссылку на абзац.</li>
+ <li>Держите подсчет количества шаров на экране в некотором роде.</li>
+ <li>Увеличьте количество и покажите обновленное количество шаров каждый раз, когда шар добавляется в сцену.</li>
+ <li>Уменьшите счет и покажите обновленное количество мячей каждый раз, когда злой круг ест шарик (его не существует).</li>
+ </ul>
+ </li>
+</ol>
+
+<h2 id="Советы_и_подсказки">Советы и подсказки</h2>
+
+<ul>
+ <li>Эта оценка довольно сложная. Делайте каждый шаг медленно и осторожно.</li>
+ <li>Может быть, идея сохранить отдельную копию демонстрации после того, как вы получите каждый этап работы, так что вы можете вернуться к ней, если позже окажетесь в беде.</li>
+</ul>
+
+<h2 id="Assessment">Assessment</h2>
+
+<p>Если вы проводите эту оценку в рамках организованного курса, вы должны уметь отдать свою работу своему учителю / наставнику для маркировки. Если вы самообучаетесь, то вы можете получить руководство по маркировке довольно легко, задав <a href="https://discourse.mozilla.org/t/adding-features-to-our-bouncing-balls-demo-assessment/24689">тему обсуждения для этого упражнения</a> или в IRC-канале <a href="irc://irc.mozilla.org/mdn">#mdn</a> в <a href="https://wiki.mozilla.org/IRC">Mozilla IRC</a>. Сначала попробуйте упражнение - ничего не выиграть от обмана!</p>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Object_building_practice", "", "Learn/JavaScript/Objects")}}</p>
+
+
+
+<h2 id="In_this_module">In this module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics">Object basics</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS">Object-oriented JavaScript for beginners</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_prototypes">Object prototypes</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Inheritance">Inheritance in JavaScript</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/JSON">Working with JSON data</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_building_practice">Object building practice</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">Adding features to our bouncing balls demo</a></li>
+</ul>
+
+
+
+<div class="s3gt_translate_tooltip_mini_box" id="s3gt_translate_tooltip_mini" style="background: initial !important; border: initial !important; border-radius: initial !important; border-collapse: initial !important; direction: ltr !important; font-weight: initial !important; height: initial !important; letter-spacing: initial !important; max-width: initial !important; min-height: initial !important; margin: auto !important; outline: initial !important; padding: initial !important; position: absolute; text-align: initial !important; text-shadow: initial !important; width: initial !important; display: initial !important; color: inherit !important; font-size: 13px !important; font-family: X-LocaleSpecific, sans-serif, Tahoma, Helvetica !important; line-height: 13px !important; vertical-align: top !important; white-space: inherit !important; left: 112px; top: 698px; opacity: 0;">
+<div class="s3gt_translate_tooltip_mini" id="s3gt_translate_tooltip_mini_logo" style="width: 12px; height: 12px; border-radius: 4px;" title="Перевести выделенный фрагмент"></div>
+
+<div class="s3gt_translate_tooltip_mini" id="s3gt_translate_tooltip_mini_sound" style="width: 12px; height: 12px; border-radius: 4px;" title="Прослушать"></div>
+
+<div class="s3gt_translate_tooltip_mini" id="s3gt_translate_tooltip_mini_copy" style="width: 12px; height: 12px; border-radius: 4px;" title="Скопировать текст в буфер обмена"></div>
+</div>
diff --git a/files/ru/learn/javascript/объекты/index.html b/files/ru/learn/javascript/объекты/index.html
new file mode 100644
index 0000000000..9acc354feb
--- /dev/null
+++ b/files/ru/learn/javascript/объекты/index.html
@@ -0,0 +1,47 @@
+---
+title: Введение в объекты JavaScript
+slug: Learn/JavaScript/Объекты
+tags:
+ - JavaScript
+ - Начинающим
+ - Объекты
+ - Руководства
+translation_of: Learn/JavaScript/Objects
+---
+<div>{{LearnSidebar}}</div>
+
+<p class="summary">В JavaScript большинство сущностей являются объектами, начиная с самого основного функционала JavaScript, такого как строки (strings) и массивы (array), и заканчивая встроенными в браузер API. Вы можете даже создавать свои собственные объекты, чтобы инкапсулировать связанные между собой функции и переменные в эффективные пакеты и действовать как удобные хранилища данных. Понимание объектно-ориентированной природы JavaScript очень важно, если Вы хотите продолжить дальнейшее более углубленное изучение языка. Поэтому мы предоставляем Вам данный модуль, чтобы помочь Вам разобраться в этом. Здесь мы детально обучим Вас теории и синтаксису объектов, а затем рассмотрим, как создавать свои собственные объекты. </p>
+
+<h2 id="Необходимые_знания">Необходимые знания</h2>
+
+<p>Перед тем, как начать изучение данного модуля, Вы должны иметь некоторое представление о HTML и CSS. Мы советуем Вам поработать над разделами <a href="https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Introduction">Введение в HTML</a> и <a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/Introduction_to_CSS">Введение в CSS</a> перед изучением этого модуля JavaScript.</p>
+
+<p>Также Вам необходимо знать основы JavaScript перед подробным изучением объектов JavaScript. Предварительно поработайте с разделами <a href="/en-US/docs/Learn/JavaScript/First_steps">Первые шаги в JavaScript</a> и <a href="/en-US/docs/Learn/JavaScript/Building_blocks">Структурные элементы в JavaScript</a> перед началом изучения данного модуля.</p>
+
+<div class="note">
+<p><span style="font-size: 14px;"><strong>Примечание</strong></span>: Если Вы работаете за компьютером/планшетом/другим устройством, на котором у Вас нет возможности создавать собственные файлы, постарайтесь поработать с примерами кода на платформах онлайн-программирования, таких, как <a href="http://jsbin.com/">JSBin</a> or <a href="https://thimble.mozilla.org/">Thimble</a>.</p>
+</div>
+
+<h2 id="Руководства">Руководства</h2>
+
+<dl>
+ <dt><a href="/ru/docs/Learn/JavaScript/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B/%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D1%8B">Основы объектов</a></dt>
+ <dd>В первой статье мы рассмотрим объекты в JavaScript. Мы будем разбирать основы синтаксиса объектов JavaScript и заново изучим некоторый функционал JavaScript, который мы уже исследовали ранее на курсе, подтвердив тот факт, что большая часть функционала, с которым мы уже столкнулись, в действительности является объектами.</dd>
+ <dt><a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS">Объектно-ориентированный JavaScript для начинающих</a></dt>
+ <dd>Закончив с основами, мы сфокусируемся на объектно-ориентированном JavaScript (OOJS) —  эта статья представляет основы теории объектно-ориентированного программирования (ООП). Затем мы изучим, как JavaScript эмулирует классы объектов через конструктор функций, и как создавать экземпляры объектов.</dd>
+ <dt><a href="/en-US/docs/Learn/JavaScript/Objects/Object_prototypes">Прототипы объектов</a></dt>
+ <dd>Прототипы - это механизм, благодаря которому объекты в JavaScript наследуют функционал друг друга, но при этом они работают иначе по сравнению с механизмами наследования в классических объектно-ориентированных языках. В этой статье мы изучим эти отличия, объясним, как работает цепочка прототипов, и рассмотрим, как свойство прототипа может быть использовано для добавления методов к существующим конструкторам.</dd>
+ <dt><a href="/en-US/docs/Learn/JavaScript/Objects/Inheritance">Наследование в JavaScript</a></dt>
+ <dd>После знакомства с самыми жуткими подробностями OOJS, эта статья покажет, как создавать "дочерные" классы объектов (конструкторы), которые наследуют функционал от своих "родительских" классов. В дополнении, мы дадим Вам пару советов о том, где и когда можно использовать OOJS.</dd>
+ <dt><a href="/en-US/docs/Learn/JavaScript/Objects/JSON">Работа с JSON-данными</a></dt>
+ <dd>Представление объектов в JavaScript (JavaScript Object Notation) (JSON) - это стандартный формат для представления структурированных данных в виде объектов JavaScript, который обычно используется для представления и передачи данных на веб-сайтах (т.е. передача некоторых данных от сервера к клиенту - таким образом они могут быть отображены на веб-странице). Вы довольно часто будете с этим сталкиваться, поэтому в данной статье мы предоставим вам все, что необходимо для работы с JSON с помощью JavaScript, в том числе доступ к элементам данных в объекте JSON и написания собственного JSON-кода.</dd>
+ <dt><a href="/en-US/docs/Learn/JavaScript/Objects/Object_building_practice">Практика построения объектов</a></dt>
+ <dd>В предыдущих статьях мы рассматривали самые основные моменты в теории и синтаксисе объектов в JavaScript, дав Вам твердую основу для начала. В этой статье мы погрузимся в практические занятия, получим больше практической работы в построении собственных объектов в JavaScript, чтобы сделать кое-что веселое и красочное - несколько цветных прыгающих шариков.</dd>
+</dl>
+
+<h2 id="Задания">Задания</h2>
+
+<dl>
+ <dt><a href="/en-US/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">Добавление функционала к демо с прыгающими шариками</a></dt>
+ <dd>В этом задании, мы ожидаем, что Вы, используя демо с прыгающими шариками из предыдущей статьи как отправную точку, добавите немного нового и интересного функционала в него.</dd>
+</dl>
diff --git a/files/ru/learn/javascript/объекты/inheritance/index.html b/files/ru/learn/javascript/объекты/inheritance/index.html
new file mode 100644
index 0000000000..c1565cd72f
--- /dev/null
+++ b/files/ru/learn/javascript/объекты/inheritance/index.html
@@ -0,0 +1,266 @@
+---
+title: Наследование в JavaScript
+slug: Learn/JavaScript/Объекты/Inheritance
+tags:
+ - JavaScript
+ - Наследование
+ - ООП
+translation_of: Learn/JavaScript/Objects/Inheritance
+---
+<p>
+ <audio class="audio-for-speech"></audio>
+</p>
+
+<div class="translate-tooltip-mtz hidden">
+<div class="header">
+<div class="header-controls"></div>
+
+<div class="translate-icons"><img class="from" src=""> <img class="arrow"> <img class="to" src=""></div>
+</div>
+
+<div class="translated-text">
+<div class="words"></div>
+
+<div class="sentences"></div>
+</div>
+</div>
+
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects")}}</div>
+
+<p class="summary">Теперь, когда объясняется большая часть подробностей OOJS, эта статья показывает, как создавать «дочерние» классы объектов (конструкторы), которые наследуют признаки из своих «родительских» классов. Кроме того, мы дадим некоторые советы о том, когда и где вы можете использовать OOJS , и посмотрим, как классы рассматриваются в современном синтаксисе ECMAScript.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Необходимые знания:</th>
+ <td>
+ <p>Базовая компьютерная грамотность, понимание основ HTML и CSS, знакомство с основами JavaScript (см. <a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9F%D0%B5%D1%80%D0%B2%D1%8B%D0%B5_%D1%88%D0%B0%D0%B3%D0%B8">Первые шаги</a> и <a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/Building_blocks">Структурные элементы</a>) and основы Объектно-ориентированного JS (см. <a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B/%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D1%8B">Введение в объекты</a>).</p>
+ </td>
+ </tr>
+ <tr>
+ <th scope="row">Цель:</th>
+ <td>Понять, как можно реализовать наследование в JavaScript.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Прототипное_наследование">Прототипное наследование</h2>
+
+<p>До сих пор мы видели некоторое наследование в действии - мы видели, как работают прототипы и как элементы наследуются, поднимаясь по цепочке. Но в основном это связано с встроенными функциями браузера. Как создать объект в JavaScript, который наследует от другого объекта?</p>
+
+<p>Давайте рассмотрим, как это сделать на конкретном примере.</p>
+
+<h2 id="Начало_работы">Начало работы</h2>
+
+<p>Прежде всего сделайте себе локальную копию нашего файла <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/oojs-class-inheritance-start.html">oojs-class-inheritance-start.html</a> (он также работает <a href="https://mdn.github.io/learning-area/javascript/oojs/advanced/oojs-class-inheritance-start.html">в режиме реального времени</a>). В файле вы найдете тот же пример конструктора <code>Person()</code>, который мы использовали на протяжении всего модуля, с небольшим отличием - мы определили внутри конструктора только лишь свойства:</p>
+
+<pre class="brush: js notranslate">function Person(first, last, age, gender, interests) {
+ this.name = {
+ first,
+ last
+ };
+ this.age = age;
+ this.gender = gender;
+ this.interests = interests;
+};</pre>
+
+<p><em>Все</em> методы определены в прототипе конструктора. Например:</p>
+
+<pre class="brush: js notranslate">Person.prototype.greeting = function() {
+ alert('Hi! I\'m ' + this.name.first + '.');
+};</pre>
+
+<div class="note">
+<p><strong>Примечание</strong>. В исходном коде вы также увидите определенные методы <code>bio()</code> и <code>farewell()</code>. Позже вы увидите, как они могут быть унаследованы другими конструкторами.</p>
+</div>
+
+<p>Скажем так, мы хотели создать класс <code>Teacher</code>, подобный тому, который мы описали в нашем первоначальном объектно-ориентированном определении, которое наследует всех членов от <code>Person</code>, но также включает в себя:</p>
+
+<ol>
+ <li>Новое свойство, <code>subject</code> - оно будет содержать предмет, который преподает учитель.</li>
+ <li>Обновленный метод <code>greeting()</code>, который звучит немного более формально, чем стандартный метод <code>greeting()</code>— более подходит для учителя, обращающегося к некоторым ученикам в школе.</li>
+</ol>
+
+<h2 id="Определение_функции-конструктора_Teacher">Определение функции-конструктора Teacher()</h2>
+
+<p>Первое, что нам нужно сделать, это создать конструктор <code>Teacher()</code> - добавьте ниже следующий код:</p>
+
+<pre class="brush: js notranslate">function Teacher(first, last, age, gender, interests, subject) {
+ Person.call(this, first, last, age, gender, interests);
+
+ this.subject = subject;
+}</pre>
+
+<p>Это похоже на конструктор Person во многих отношениях, но здесь есть что-то странное, что мы не видели раньше - функцию <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call">call()</a></code>. Эта функция в основном позволяет вам вызывать функцию, определенную где-то в другом месте, но в текущем контексте. Первый параметр указывает значение <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this">this</a></code>, которое вы хотите использовать при выполнении функции, а остальные параметры - те, которые должны быть переданы функции при ее вызове.</p>
+
+<p>Мы хотим, чтобы конструктор <code>Teacher()</code> принимал те же параметры, что и конструктор <code>Person()</code>, от которго он наследуется, поэтому мы указываем их как параметры в вызове <code>call()</code>.</p>
+
+<p>Последняя строка внутри конструктора просто определяет новое свойство <code>subject</code>, которое будут иметь учителя, и которого нет у Person().</p>
+
+<p>В качестве примечания мы могли бы просто сделать это:</p>
+
+<pre class="brush: js notranslate">function Teacher(first, last, age, gender, interests, subject) {
+ this.name = {
+ first,
+ last
+ };
+ this.age = age;
+ this.gender = gender;
+ this.interests = interests;
+ this.subject = subject;
+}</pre>
+
+<p>Но это просто переопределяет свойства заново, а не наследует их от <code>Person()</code>, так что теряется смысл того, что мы пытаемся сделать. Он также занимает больше строк кода.</p>
+
+<h3 id="Наследование_от_конструктора_без_параметров">Наследование от конструктора без параметров</h3>
+
+<p>Обратите внимание, что если конструктор, от которого вы наследуете, не принимает значения своего свойства из параметров, вам не нужно указывать их в качестве дополнительных аргументов в <code>call()</code>. Так, например, если у вас было что-то действительно простое:</p>
+
+<pre class="brush: js notranslate">function Brick() {
+ this.width = 10;
+ this.height = 20;
+}</pre>
+
+<p>Вы можете наследовать свойства <code>width</code> и <code>height</code>, выполнив это (как и другие шаги, описанные ниже, конечно):</p>
+
+<pre class="brush: js notranslate">function BlueGlassBrick() {
+ Brick.call(this);
+
+ this.opacity = 0.5;
+ this.color = 'blue';
+}</pre>
+
+<p>Обратите внимание, что мы указали только <code>this</code> внутри <code>call()</code> - никаких других параметров не требуется, поскольку мы не наследуем никаких свойств родителя, которые задаются через параметры.</p>
+
+<h2 id="Установка_Teachers_prototype_и_конструктор_ссылок">Установка Teacher()'s prototype и конструктор ссылок</h2>
+
+<p>Пока все хорошо, но у нас есть проблема. Мы определили новый конструктор и у него есть свойство <code>prototype</code>, которое по умолчанию просто содержит ссылку на саму конструкторскую функцию. Он не содержит методов свойства <code>prototype</code> конструктора <code>Person</code>. Чтобы увидеть это, введите <code>Object.getOwnPropertyNames(Teacher.prototype)</code> в поле ввода текста или в вашу консоль JavaScript. Затем введите его снова, заменив <code>Teacher</code> на <code>Person</code>. Новый конструктор <em>не наследует</em> эти методы. Чтобы увидеть это, сравните выводы в консоль <code>Person.prototype.greeting</code> и <code>Teacher.prototype.greeting</code>. Нам нужно заставить <code>Teacher()</code> наследовать методы, определенные на прототипе <code>Person()</code>. Итак, как мы это делаем?</p>
+
+<ol>
+ <li>Добавьте следующую строку ниже своего предыдущего добавления:
+ <pre class="brush: js notranslate">Teacher.prototype = Object.create(Person.prototype);</pre>
+ Здесь наш друг <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create">create()</a></code> снова приходит на помощь. В этом случае мы используем его для создания нового объекта и делаем его значением <code>Teacher.prototype</code>. Новый объект имеет свой прототип <code>Person.prototype</code> и, следовательно, наследует, если и когда это необходимо, все доступные методы <code>Person.prototype</code>.</li>
+ <li>Нам нужно сделать еще одну вещь, прежде чем двигаться дальше. После добавления последней строки, <code>Teacher.prototype.constructor</code> стало равным <code>Person()</code>, потому что мы просто устанавливаем <code>Teacher.prototype</code> для ссылки на объект, который наследует его свойства от <code>Person.prototype</code>! Попробуйте сохранить код, загрузите страницу в браузере и введите <code>Teacher.prototype.constructor</code> в консоль для проверки.</li>
+ <li>Это может стать проблемой, поэтому нам нужно сделать это правильно. Вы можете сделать это, вернувшись к исходному коду и добавив следующие строки внизу:
+ <pre class="notranslate"><code>Object.defineProperty(Teacher.prototype, 'constructor', {
+ value: Teacher,
+ enumerable: false, // false, чтобы данное свойство не появлялось в цикле for in
+ writable: true });</code></pre>
+ </li>
+ <li>Теперь, если вы сохраните и обновите, введите <code>Teacher.prototype.constructor</code>, чтобы вернуть <code>Teacher()</code>, плюс мы теперь наследуем <code>Person()</code>!</li>
+</ol>
+
+<h2 id="Предоставление_Teacher_новой_функции_greeting">Предоставление Teacher() новой функции greeting()</h2>
+
+<p>Чтобы завершить наш код, нам нужно определить новую функцию <code>greeting()</code> в конструкторе <code>Teacher()</code>.</p>
+
+<p>Самый простой способ сделать это - определить его на прототипе <code>Teacher()</code> - добавить в нижнюю часть кода следующее:</p>
+
+<pre class="brush: js notranslate">Teacher.prototype.greeting = function() {
+ var prefix;
+
+ if (this.gender === 'male' || this.gender === 'Male' || this.gender === 'm' || this.gender === 'M') {
+ prefix = 'Mr.';
+ } else if (this.gender === 'female' || this.gender === 'Female' || this.gender === 'f' || this.gender === 'F') {
+ prefix = 'Mrs.';
+ } else {
+ prefix = 'Mx.';
+ }
+
+ alert('Hello. My name is ' + prefix + ' ' + this.name.last + ', and I teach ' + this.subject + '.');
+};</pre>
+
+<p>Это выводит на экран приветствие учителя, в котором используется соответствующий префикс имени для своего пола, разработанный с использованием условного оператора.</p>
+
+<h2 id="Попробуйте_пример">Попробуйте пример</h2>
+
+<p>Теперь, когда вы ввели весь код, попробуйте создать экземпляр объекта из <code>Teacher()</code>, поставив ниже вашего JavaScript кода (или что-то похожее по вашему выбору):</p>
+
+<pre class="brush: js notranslate">var teacher1 = new Teacher('Dave', 'Griffiths', 31, 'male', ['football', 'cookery'], 'mathematics');</pre>
+
+<p>Теперь сохраните, обновите, и попробуйте получить доступ к свойствам и методам вашего нового объекта <code>teacher1</code>, например:</p>
+
+<pre class="brush: js notranslate">teacher1.name.first;
+teacher1.interests[0];
+teacher1.bio();
+teacher1.subject;
+teacher1.greeting();
+teacher1.farewell();</pre>
+
+<p>Все должно работать нормально. Запросы в строках 1, 2, 3 и 6 унаследованны от общего конструктора <code>Person()</code> (класса). Запрос в строке 4 обращается к <code>subject</code>, доступному только для более специализированного конструктора (класса) <code>Teacher()</code>. Запрос в строке 5 получил бы доступ к методу <code>greeting()</code>, унаследованному от <code>Person()</code>, но <code>Teacher()</code> имеет свой собственный метод <code>greeting()</code> с тем же именем, поэтому запрос обращается к этому методу.</p>
+
+<div class="note">
+<p><strong>Примечание</strong>. Если вам не удается заставить это работать, сравните свой код с нашей <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/oojs-class-inheritance-finished.html">готовой версией</a> (см. также <a href="http://mdn.github.io/learning-area/javascript/oojs/advanced/oojs-class-inheritance-student.html">рабочее демо</a>).</p>
+</div>
+
+<p>Методика, которую мы здесь рассмотрили, - это не единственный способ создания наследующих классов в JavaScript, но он работает нормально и это дает вам представление о том, как реализовать наследование в JavaScript.</p>
+
+<p>Вам также может быть интересно узнать некоторые из новых функций {{glossary("ECMAScript")}}, которые позволяют нам делать наследование более чисто в JavaScript (см. <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes">Classes</a>). Мы не рассматривали их здесь, поскольку они пока не поддерживаются очень широко в браузерах. Все остальные конструкторы кода, которые мы обсуждали в этом наборе статей, поддерживаются еще в IE9 или ранее и есть способы добиться более ранней поддержки, чем это.</p>
+
+<p>Обычный способ - использовать библиотеку JavaScript - большинство популярных опций имеют простой набор функций, доступных для выполнения наследования более легко и быстро. <a href="http://coffeescript.org/#classes">CoffeeScript</a> , например, предоставляет класс, расширяет и т.д.</p>
+
+<h2 id="Дальнейшее_упражнение">Дальнейшее упражнение</h2>
+
+<p>В нашем <a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS#Object-oriented_programming_from_10000_meters">руководстве по Объектно-ориентированному JavaScript для начинающих</a> мы также включили класс <code>Student</code> как концепцию, которая наследует все особенности <code>Person</code>, а также имеет другой метод <code>greeting()</code> от <code>Person</code>, который гораздо более неформален, чем приветствие <code>Teacher</code>. Посмотрите, как выглядит приветствие ученика в этом разделе, и попробуйте реализовать собственный конструктор <code>Student()</code>, который наследует все функции <code>Person()</code> и реализует другую функцию <code>greeting()</code>.</p>
+
+<div class="note">
+<p><strong>Примечание</strong>. Если вам не удается заставить это работать, сравните свой код с нашей <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/oojs-class-inheritance-student.html">готовой версией</a> (см. также <a href="http://mdn.github.io/learning-area/javascript/oojs/advanced/oojs-class-inheritance-student.html">рабочее демо</a>).</p>
+</div>
+
+<h2 id="Object_member_summary">Object member summary</h2>
+
+<p>Подводя итог, вы в основном получили три типа свойств / методов, о которых нужно беспокоиться:</p>
+
+<ol>
+ <li>Те, которые определены внутри функции-конструктора, которые присваиваются экземплярам объекта. Их довольно легко заметить - в вашем собственном коде они представляют собой элементы, определенные внутри конструктора, используя строки <code>this.x = x</code>; в встроенном коде браузера они являются членами, доступными только для экземпляров объектов (обычно создаются путем вызова конструктора с использованием ключевого слова <code>new</code>, например <code>var myInstance = new myConstructor ()</code>.</li>
+ <li>Те, которые определяются непосредственно самим конструктором, которые доступны только для конструктора. Они обычно доступны только для встроенных объектов браузера и распознаются путем непосредственной привязки к конструктору, а не к экземпляру. Например, <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys">Object.keys()</a></code>.</li>
+ <li>Те, которые определены в прототипе конструктора, которые наследуются всеми экземплярами и наследуют классы объектов. К ним относятся любой член, определенный в свойстве прототипа конструктора, например. <code>myConstructor.prototype.x()</code>.</li>
+</ol>
+
+<p>Если вы не уверены, что это такое, не беспокойтесь об этом, пока вы еще учитесь и знание придет с практикой.</p>
+
+<h2 id="Когда_вы_используете_наследование_в_JavaScript">Когда вы используете наследование в JavaScript?</h2>
+
+<p>В частности, после этой последней статьи вы можете подумать: «У-у-у, это сложно». Ну, ты прав. Прототипы и наследование представляют собой некоторые из самых сложных аспектов JavaScript, но многие возможности и гибкость JavaScript вытекают из его структуры объектов и наследования и стоит понять, как это работает.</p>
+
+<p>В некотором смысле вы используете наследование все время. Всякий раз, когда вы используете различные функции веб-API или методы/свойства, определенные во встроенном объекте браузера, который вы вызываете в своих строках, массивах и т.д., вы неявно используете наследование.</p>
+
+<p>Что касается использования наследования в вашем собственном коде, вы, вероятно, не будете часто его использовать, особенно для начала и в небольших проектах. Это пустая трата времени на использование объектов и наследование только ради этого, когда они вам не нужны. Но по мере того, как ваши базы кода становятся больше, вы с большей вероятностью найдете необходимость в этом. Если вы начинаете создавать несколько объектов с подобными функциями, то создание универсального типа объекта, содержащего все общие функции и наследование этих функций в более специализированных типах объектов, может быть удобным и полезным.</p>
+
+<div class="note">
+<p><strong>Примечание</strong>. Из-за того, как работает JavaScript, с цепочкой прототипов и т.д., совместное использование функций между объектами часто называется <strong>делегированием</strong>. Специализированные объекты делегируют функциональность универсальному типу объекта.</p>
+</div>
+
+<p>При использовании наследования вам рекомендуется не иметь слишком много уровней наследования и тщательно отслеживать, где вы определяете свои методы и свойства. Можно начать писать код, который временно изменяет прототипы встроенных объектов браузера, но вы не должны этого делать, если у вас нет действительно веской причины. Слишком много наследования могут привести к бесконечной путанице и бесконечной боли при попытке отладки такого кода.</p>
+
+<p>В конечном счете, объекты - это еще одна форма повторного использования кода, например функций или циклов, со своими конкретными ролями и преимуществами. Если вы обнаруживаете, что создаете кучу связанных переменных и функций и хотите отслеживать их все вместе и аккуратно их упаковывать, объект является хорошей идеей. Объекты также очень полезны, когда вы хотите передать коллекцию данных из одного места в другое. Обе эти вещи могут быть достигнуты без использования конструкторов или наследования. Если вам нужен только один экземпляр объекта, вам лучше всего использовать литерал объекта и вам, разумеется, не нужно наследование.</p>
+
+<h2 id="Резюме">Резюме</h2>
+
+<p>В этой статье мы рассмотрели оставшуюся часть основной теории и синтаксиса OOJS, которые, как мы думаем, вам следует знать сейчас. На этом этапе вы должны понимать основы JavaScript, ООП, прототипы и прототипное наследование, как создавать классы (конструкторы) и экземпляры объектов, добавлять функции в классы и создавать подклассы, которые наследуются от других классов.</p>
+
+<p>В следующей статье мы рассмотрим, как работать с JavaScript Object Notation (JSON), общим форматом обмена данными, написанным с использованием объектов JavaScript.</p>
+
+<h2 id="See_also">See also</h2>
+
+<ul>
+ <li><a href="http://www.objectplayground.com/">ObjectPlayground.com</a> — A really useful interactive learning site for learning about objects.</li>
+ <li><a href="https://www.amazon.com/gp/product/193398869X/">Secrets of the JavaScript Ninja</a>, Chapter 6 — A good book on advanced JavaScript concepts and techniques, by John Resig and Bear Bibeault. Chapter 6 covers aspects of prototypes and inheritance really well; you can probably track down a print or online copy fairly easily.</li>
+ <li><a href="https://github.com/getify/You-Dont-Know-JS/blob/master/this%20&amp;%20object%20prototypes/README.md#you-dont-know-js-this--object-prototypes">You Don't Know JS: this &amp; Object Prototypes</a> — Part of Kyle Simpson's excellent series of JavaScript manuals, Chapter 5 in particular looks at prototypes in much more detail than we do here. We've presented a simplified view in this series of articles aimed at beginners, whereas Kyle goes into great depth and provides a more complex but more accurate picture.</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects")}}</p>
+
+<h2 id="В_этом_модуле">В этом модуле</h2>
+
+<ul>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/Объекты/Основы">Основы объекта</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/Объекты/Object-oriented_JS">Объектно-ориентированный JavaScript для начинающих</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/Объекты/Object_prototypes">Прототипы объектов</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/Объекты/Inheritance">Наследование в JavaScript</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/Объекты/JSON">Работа с данными JSON</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/Объекты/Object_building_practice">Практика построения объектов</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/Объекты/Adding_bouncing_balls_features">Добавление функций в нашу демонстрацию прыгающих шаров</a></li>
+</ul>
diff --git a/files/ru/learn/javascript/объекты/json/index.html b/files/ru/learn/javascript/объекты/json/index.html
new file mode 100644
index 0000000000..371f254ec6
--- /dev/null
+++ b/files/ru/learn/javascript/объекты/json/index.html
@@ -0,0 +1,353 @@
+---
+title: Работа с JSON
+slug: Learn/JavaScript/Объекты/JSON
+tags:
+ - Beginner
+ - JSON
+ - JavaScript
+translation_of: Learn/JavaScript/Objects/JSON
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects/Object_building_practice", "Learn/JavaScript/Objects")}}</div>
+
+<p class="summary">Обозначение объектов JavaScript (JSON - JavaScript Object Notation) - стандартный текстовый формат для представления структурированных данных на основе синтаксиса объекта JavaScript. Он обычно используется для передачи данных в веб-приложениях (например, отправка некоторых данных с сервера клиенту,таким образом чтобы это могло отображаться на веб-странице или наоборот). Вы будете сталкиваться с этим довольно часто, поэтому в этой статье мы даем вам все, что вам нужно для работы с JSON используя JavaScript, включая парсинг JSON, чтобы вы могли получить доступ к данным внутри него при создании JSON.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Необходимые знания:</th>
+ <td>Базовая компьютерная грамотность, базовые знания HTML и CSS, знакомство с основами JavaScript (см. <a href="/en-US/docs/Learn/JavaScript/First_steps">First steps</a> и <a href="/en-US/docs/Learn/JavaScript/Building_blocks">Building blocks</a>) и основами OOJS  (see <a href="/en-US/docs/Learn/JavaScript/Object-oriented/Introduction">Introduction to objects</a>).</td>
+ </tr>
+ <tr>
+ <th scope="row">Цель:</th>
+ <td>Понять, как работать с данными, хранящимися в JSON, и создавать свои собственные объекты JSON.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Нет_действительно_что_такое_JSON">Нет, действительно, что такое JSON?</h2>
+
+<p>{{glossary("JSON")}} - текстовый формат данных, следующий за синтаксисом объекта JavaScript, который был популяризирован <a href="https://en.wikipedia.org/wiki/Douglas_Crockford">Дугласом Крокфордом</a>. Несмотря на то, что он очень похож на буквенный синтаксис объекта JavaScript, его можно использовать независимо от JavaScript, и многие среды программирования имеют возможность читать (анализировать) и генерировать JSON.</p>
+
+<p>JSON существует как строка,что необходимо при передаче данных по сети. Он должен быть преобразован в собственный объект JavaScript, если вы хотите получить доступ к данным. Это не большая проблема. JavaScript предоставляет глобальный объект <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON">JSON</a>, который имеет методы для преобразования между ними.</p>
+
+<div class="note">
+<p><strong>Примечание</strong>: Преобразование строки в родной объект называется десериализацией (преобразование из последовательной формы в параллельную<em>)</em>, в то время как преобразовании родного объекта в строку, таким образом ,чтобы он мог быть передан через сеть, называется сериализацией(преобразование в последовательную форму).</p>
+</div>
+
+<p>Объект JSON может быть сохранен в собственном файле, который в основном представляет собой текстовый файл с расширением <code>.json</code> и {{glossary("MIME type")}} <code>application/json</code>.</p>
+
+<h3 id="Структура_JSON">Структура JSON</h3>
+
+<p>Как описано выше, JSON представляет собой строку, формат которой очень похож на буквенный формат объекта JavaScript. Вы можете включать одни и те же базовые типы данных внутри JSON, так же как и  в стандартном объекте JavaScript - строки, числа, массивы, булевы и другие объектные литералы. Это позволяет построить иерархию данных, к примеру, так:</p>
+
+<pre class="brush: json">{
+  "squadName": "Super hero squad",
+  "homeTown": "Metro City",
+  "formed": 2016,
+  "secretBase": "Super tower",
+ "active": true,
+  "members": [
+    {
+      "name": "Molecule Man",
+      "age": 29,
+      "secretIdentity": "Dan Jukes",
+      "powers": [
+        "Radiation resistance",
+        "Turning tiny",
+        "Radiation blast"
+      ]
+    },
+    {
+      "name": "Madame Uppercut",
+      "age": 39,
+      "secretIdentity": "Jane Wilson",
+      "powers": [
+        "Million tonne punch",
+        "Damage resistance",
+        "Superhuman reflexes"
+      ]
+    },
+    {
+      "name": "Eternal Flame",
+      "age": 1000000,
+      "secretIdentity": "Unknown",
+      "powers": [
+        "Immortality",
+        "Heat Immunity",
+        "Inferno",
+        "Teleportation",
+        "Interdimensional travel"
+      ]
+    }
+  ]
+}</pre>
+
+<p>Если бы мы загрузили этот объект в программу JavaScript, создали переменную с названием <code>superHeroes</code>, мы могли бы затем получить доступ к данным внутри нее, используя те же самые точечную и скобочную нотации, которые мы рассмотрели в статье <a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics">JavaScript object basics</a>. Например:</p>
+
+<pre class="brush: js">superHeroes.homeTown
+superHeroes['active']</pre>
+
+<p>Чтобы получить доступ к последующим данным  по иерархии, вам просто нужно объединить требуемые имена свойств и индексы массивов. Например, чтобы получить доступ к третьей сверхспособности второго героя, указанного в списке участников, вы должны сделать следующее:</p>
+
+<pre class="brush: js">superHeroes['members'][1]['powers'][2]</pre>
+
+<ol>
+ <li>Сначала у нас есть имя переменной - <code>superHeroes</code>.</li>
+ <li>Внутри мы хотим получить доступ к свойству <code>members</code>, поэтому мы используем <code>['members']</code>.</li>
+ <li><code>members</code> содержат массив, заполненный объектами. Мы хотим получить доступ ко второму объекту внутри массива, поэтому мы используем <code>[1]</code>.</li>
+ <li>Внутри этого объекта мы хотим получить доступ к свойству <code>powers</code>, поэтому мы используем <code>['powers']</code>.</li>
+ <li>Внутри свойства <code>powers</code> находится массив, содержащий сверхспособности выбранного героя. Нам нужен третий, поэтому мы используем <code>[2]</code>.</li>
+</ol>
+
+<div class="note">
+<p><strong>Примечание</strong>. Мы сделали JSON, видимый выше, доступным внутри переменной в нашем примере <a href="http://mdn.github.io/learning-area/javascript/oojs/json/JSONTest.html">JSONTest.html</a> (см. <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/json/JSONTest.html">исходный код</a>). Попробуйте загрузить это, а затем получить доступ к данным внутри переменной через консоль JavaScript вашего браузера.</p>
+</div>
+
+<h3 id="Массивы_как_JSON">Массивы как JSON</h3>
+
+<p>Выше мы упоминали ,что JSON текст выглядит практически так же как и JavaScript объект,и это почти правильно.Причина,по которой мы говорим почти правильно заключается в том ,что массив также валиден JSON  например:</p>
+
+<pre class="brush: json">[
+ {
+ "name": "Molecule Man",
+ "age": 29,
+ "secretIdentity": "Dan Jukes",
+ "powers": [
+ "Radiation resistance",
+ "Turning tiny",
+ "Radiation blast"
+ ]
+ },
+ {
+    "name": "Madame Uppercut",
+    "age": 39,
+    "secretIdentity": "Jane Wilson",
+    "powers": [
+      "Million tonne punch",
+      "Damage resistance",
+      "Superhuman reflexes"
+    ]
+  }
+]</pre>
+
+<p>Вышесказанное вполне справедливо для JSON. Вам просто нужно получить доступ к элементам массива (в его анализируемой версии), начиная с индекса массива, например <code>[0]["powers"][0]</code>.</p>
+
+<h3 id="Другие_примечания">Другие примечания</h3>
+
+<ul>
+ <li>JSON - это чисто формат данных - он содержит только свойства, без методов.</li>
+ <li>JSON требует двойных кавычек, которые будут использоваться вокруг строк и имен свойств. Одиночные кавычки недействительны.</li>
+ <li>Даже одна неуместная запятая или двоеточие могут привести к сбою JSON-файла и не работать. Вы должны быть осторожны, чтобы проверить любые данные, которые вы пытаетесь использовать (хотя сгенерированный компьютером JSON с меньшей вероятностью включает ошибки, если программа генератора работает правильно). Вы можете проверить JSON с помощью приложения вроде <a href="http://jsonlint.com/">JSONLint</a>.</li>
+ <li>JSON может принимать форму любого типа данных, допустимого для включения в JSON, а не только массивов или объектов. Так, например, одна строка или номер будут действительным объектом JSON.</li>
+ <li>В отличие от кода JavaScript, в котором свойства объекта могут не заключаться в двойные кавычки, в JSON в качестве свойств могут использоваться только строки заключенные в двойные кавычки.</li>
+</ul>
+
+<h2 id="Активное_обучение_Работа_с_примером_JSON">Активное обучение: Работа с примером JSON</h2>
+
+<p>Итак, давайте рассмотрим пример, чтобы показать то, как мы можем использовать некоторые данные JSON на веб-сайте.</p>
+
+<h3 id="Начало_работы">Начало работы</h3>
+
+<p>Для начала создайте локальные копии наших файлов <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/json/heroes.html">heroes.html</a> и <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/json/style.css">style.css</a>. Последний содержит простой CSS для стилизации нашей страницы, в то время как первый содержит очень простой HTML-код сущности:</p>
+
+<pre class="brush: html">&lt;header&gt;
+&lt;/header&gt;
+
+&lt;section&gt;
+&lt;/section&gt;</pre>
+
+<p>Плюс {{HTMLElement("script")}}, чтобы содержать код JavaScript, который мы будем писать в этом упражнении. На данный момент он содержит только две строки, которые захватывают ссылки на элементы {{HTMLElement("header")}} и {{HTMLElement("section")}} и сохраняют их в переменных:</p>
+
+<pre class="brush: js">var header = document.querySelector('header');
+var section = document.querySelector('section');</pre>
+
+<p>Мы предоставили данные JSON на нашем GitHub, на <a href="https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json">https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json</a>.</p>
+
+<p>Мы собираемся загрузить его на нашу страницу и использовать некоторые изящные манипуляции DOM, чтобы отобразить их, например:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13857/json-superheroes.png" style="display: block; margin: 0 auto;"></p>
+
+<h3 id="Получение_JSON">Получение JSON</h3>
+
+<p>Чтобы получить JSON, мы будем использовать API, называемый {{domxref("XMLHttpRequest")}} (часто называемый <strong>XHR</strong>). Это очень полезный объект JavaScript, который позволяет нам делать сетевые запросы для извлечения ресурсов с сервера через JavaScript (например, изображения, текст, JSON, даже фрагменты HTML), что означает, что мы можем обновлять небольшие разделы контента без необходимости перезагрузки всей страницы. Это привело к более отзывчивым веб-страницам и звучит захватывающе, но, к сожалению, выходит за рамки этой статьи, чтобы изучить это гораздо более подробно.</p>
+
+<ol>
+ <li>Начнем с того, что мы собираемся сохранить URL-адрес JSON, который мы хотим получить в переменной. Добавьте нижеследующий код JavaScript:
+ <pre class="brush: js">var requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';</pre>
+ </li>
+ <li>Чтобы создать запрос, нам нужно создать новый экземпляр объекта запроса из конструктора <code>XMLHttpRequest</code>, используя ключевое слово <code>new</code>. Добавьте следующую ниже свою последнюю строку:
+ <pre class="brush: js">var request = new XMLHttpRequest();</pre>
+ </li>
+ <li>Теперь нам нужно открыть новый запрос, используя метод <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/open">open()</a></code>. Добавьте следующую строку:
+ <pre class="brush: js">request.open('GET', requestURL);</pre>
+
+ <p>Это занимает не менее двух параметров - есть другие доступные параметры. Нам нужно только два обязательных для этого простого примера:</p>
+
+ <ul>
+ <li>Метод HTTP, который следует использовать при выполнении сетевого запроса. В этом случае <code><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET">GET</a></code> самый подходящий, так как мы просто извлекаем некоторые простые данные.</li>
+ <li>URL-адрес для запроса - это URL-адрес файла JSON, который мы сохранили ранее.</li>
+ </ul>
+ </li>
+ <li>Затем добавьте следующие две строки: здесь мы устанавливаем <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseType">responseType</a></code> в JSON, так что XHR знает, что сервер будет возвращать JSON и, что это должно быть преобразовано за кулисами в объект JavaScript. Затем мы отправляем запрос методом <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/send">send()</a></code>:
+ <pre class="brush: js">request.responseType = 'json';
+request.send();</pre>
+ </li>
+ <li>Последний бит этого раздела предполагает ожидание ответа на возврат с сервера, а затем работы с ним. Добавьте следующий код ниже вашего предыдущего кода:
+ <pre class="brush: js">request.onload = function() {
+ var superHeroes = request.response;
+ populateHeader(superHeroes);
+ showHeroes(superHeroes);
+}</pre>
+ </li>
+</ol>
+
+<p>Здесь мы сохраняем ответ на наш запрос (доступный в свойстве <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/response">response</a></code>) в переменной <code>superHeroes</code>; эта переменная теперь будет содержать объект JavaScript, основанный на JSON! Затем мы передаем этот объект двум вызовам функций - первый из них заполнит <code>&lt;header&gt;</code> правильными данными, а второй создаст информационную карту для каждого героя в команде и вставляет ее в <code>&lt;section&gt;</code>.</p>
+
+<p>Мы свернули код в обработчик событий, который запускается, когда событие загрузки запускается в объекте запроса (см. <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequestEventTarget/onload">onload</a></code>) - это связано с тем, что событие загрузки запускается, когда ответ успешно возвращается; поступая  таким образом,это гарантия того, что <code>request.response</code> определенно будет доступен, когда мы начнем работу с ним.</p>
+
+<p>Заполнение заголовка</p>
+
+<p>Теперь мы извлекли данные JSON и превратили его в объект JavaScript, давайте воспользуемся им, написав две функции, на которые мы ссылались выше. Прежде всего, добавьте следующее определение функции ниже предыдущего кода:</p>
+
+<pre class="brush: js">function populateHeader(jsonObj) {
+ var myH1 = document.createElement('h1');
+ myH1.textContent = jsonObj['squadName'];
+ header.appendChild(myH1);
+
+ var myPara = document.createElement('p');
+ myPara.textContent = 'Hometown: ' + jsonObj['homeTown'] + ' // Formed: ' + jsonObj['formed'];
+ header.appendChild(myPara);
+}</pre>
+
+<p>Мы назвали параметр <code>jsonObj</code>, чтобы напомнить себе, что этот объект JavaScript возник из JSON. Здесь мы сначала создаем элемент {{HTMLElement("h1")}} с <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement">createElement()</a></code>, устанавливаем его <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent">textContent</a></code> равным свойству <code>squadName</code> объекта, а затем добавляем его в заголовок с помощью <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild">appendChild()</a></code>. Затем мы выполняем очень похожую операцию с абзацем: создаем его, устанавливаем его текстовое содержимое и добавляем его в заголовок. Единственное различие заключается в том, что его текст задан, как конкатенированная строка, содержащая как <code>homeTown</code>, так и <code>formed</code> свойства объекта.</p>
+
+<h3 id="Создание_информационных_карт_героя">Создание информационных карт героя</h3>
+
+<p>Затем добавьте следующую функцию внизу кода, которая создает и отображает карты супергероев:</p>
+
+<pre class="brush: js">function showHeroes(jsonObj) {
+ var heroes = jsonObj['members'];
+
+ for (var i = 0; i &lt; heroes.length; i++) {
+ var myArticle = document.createElement('article');
+ var myH2 = document.createElement('h2');
+ var myPara1 = document.createElement('p');
+ var myPara2 = document.createElement('p');
+ var myPara3 = document.createElement('p');
+ var myList = document.createElement('ul');
+
+ myH2.textContent = heroes[i].name;
+ myPara1.textContent = 'Secret identity: ' + heroes[i].secretIdentity;
+ myPara2.textContent = 'Age: ' + heroes[i].age;
+ myPara3.textContent = 'Superpowers:';
+
+ var superPowers = heroes[i].powers;
+ for (var j = 0; j &lt; superPowers.length; j++) {
+ var listItem = document.createElement('li');
+ listItem.textContent = superPowers[j];
+ myList.appendChild(listItem);
+ }
+
+ myArticle.appendChild(myH2);
+ myArticle.appendChild(myPara1);
+ myArticle.appendChild(myPara2);
+ myArticle.appendChild(myPara3);
+ myArticle.appendChild(myList);
+
+ section.appendChild(myArticle);
+ }
+}</pre>
+
+<p>Для начала сохраним свойство <code>members</code> объекта JavaScript в новой переменной. Этот массив содержит несколько объектов, которые содержат информацию для каждого героя.</p>
+
+<p>Затем мы используем <a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code#The_standard_for_loop">for loop</a> для циклического прохождения каждого объекта в массиве. Для каждого из них мы:</p>
+
+<ol>
+ <li>Создаем несколько новых элементов: <code>&lt;article&gt;</code>, <code>&lt;h2&gt;</code>, три <code>&lt;p&gt;</code> и <code>&lt;ul&gt;</code>.</li>
+ <li>Установливаем <code>&lt;h2&gt;</code>, чтобы содержать <code>name</code> текущего героя.</li>
+ <li>Заполняем три абзаца своей <code>secretIdentity</code>, <code>age</code> и строкой, в которой говорится: «Суперспособности:», чтобы ввести информацию в список.</li>
+ <li>Сохраняем свойство <code>powers</code> в другой новой переменной под названием <code>superPowers</code> - где содержится массив, в котором перечислены сверхспособности текущего героя.</li>
+ <li>Используем другой цикл <code>for</code>, чтобы прокрутить сверхспособности текущего героя , для каждого из них мы создаем элемент <code>&lt;li&gt;</code>, помещаем в него сверхспособности, а затем помещаем <code>listItem</code> внутри элемента <code>&lt;ul&gt;</code> (<code>myList</code>) с помощью <code>appendChild()</code>.</li>
+ <li>Последнее, что мы делаем, это добавляем <code>&lt;h2&gt;</code>, <code>&lt;p&gt;</code> и <code>&lt;ul&gt;</code> внутри <code>&lt;article&gt;</code> (<code>myArticle</code>), а затем добавляем <code>&lt;article&gt;</code> в <code>&lt;section&gt;</code>. Важное значение имеет порядок, в котором добавляются элементы, так как это порядок, который они будут отображать внутри HTML.</li>
+</ol>
+
+<div class="note">
+<p><strong>Примечание</strong>. Если вам не удается заставить этот пример работать, попробуйте обратиться к нашему исходному коду <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/json/heroes-finished.html">heroes-finished.html</a> (см. также он работает <a href="https://mdn.github.io/learning-area/javascript/oojs/json/heroes-finished.html">в режиме live</a>).</p>
+</div>
+
+<div class="note">
+<p><strong>Примечание</strong>. Если у вас возникли проблемы после нотации точек / скобок, которые мы используем для доступа к объекту JavaScript, в этом поможет открытие файла <a href="http://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json">superheroes.json</a> на другой вкладке или в текстовом редакторе ,и обращаться к нему каждый раз, когда вам нужен JavaScript. Вы также можете обратиться к нашей статье <a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics">JavaScript objectbasics</a> чтобы получить дополнительную информацию о нотации точек и скобок.</p>
+</div>
+
+<h2 id="Преобразование_между_объектами_и_текстом">Преобразование между объектами и текстом</h2>
+
+<p>Вышеприведенный пример был прост с точки зрения доступа к объекту JavaScript, потому что мы задали XHR-запрос для прямого преобразования ответа JSON в объект JavaScript, используя:</p>
+
+<pre class="brush: js">request.responseType = 'json';</pre>
+
+<p>Но иногда нам не так везет - иногда мы получаем сырую строку JSON и нам нужно  преобразовать ее в объект самостоятельно. И когда мы хотим отправить объект JavaScript по сети, нам нужно  преобразовать его в JSON (строку) перед отправкой. К счастью, эти две проблемы настолько распространены в веб-разработке, что встроенный объект <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON">JSON</a> доступен в браузерах, которые содержат следующие два метода:</p>
+
+<ul>
+ <li><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse">parse()</a></code>: принимает строку JSON в качестве параметра и возвращает соответствующий объект JavaScript.</li>
+ <li><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify">stringify()</a></code>: принимает объект, как параметр и возвращает эквивалентную строковую JSON строку.</li>
+</ul>
+
+<p>Вы можете увидеть первый метод в действии в нашем примере <a href="http://mdn.github.io/learning-area/javascript/oojs/json/heroes-finished-json-parse.html">heroes-finished-json-parse.html</a> (см. <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/json/heroes-finished-json-parse.html">исходный код</a>) - это то же самое, что и в примере, который мы создали ранее, за исключением того, что мы установили XHR для возврата сырого JSON текста, затем используется <code>parse()</code>, чтобы преобразовать его в фактический объект JavaScript. Ключевой фрагмент кода находится здесь:</p>
+
+<pre class="brush: js">request.open('GET', requestURL);
+request.responseType = 'text'; // now we're getting a string!
+request.send();
+
+request.onload = function() {
+ var superHeroesText = request.response; // get the string from the response
+ var superHeroes = JSON.parse(superHeroesText); // convert it to an object
+ populateHeader(superHeroes);
+ showHeroes(superHeroes);
+}</pre>
+
+<p>Как вы могли догадаться, <code>stringify()</code> работает обратным образом. Попробуйте ввести следующие строки в консоль JavaScript браузера один за другим, чтобы увидеть его в действии:</p>
+
+<pre class="brush: js">var myJSON = { "name": "Chris", "age": "38" };
+myJSON
+var myString = JSON.stringify(myJSON);
+myString</pre>
+
+<p>Здесь мы создаем объект JavaScript, затем проверяем, что он содержит, а затем преобразуем его в строку JSON, используя <code>stringify()</code> , сохраняя возвращаемое значение в новой переменной, а затем снова проверяем его.</p>
+
+<h2 id="Резюме">Резюме</h2>
+
+<p>В этой статье мы предоставили вам простое руководство по использованию JSON в ваших программах, в том числе о том, как создавать и анализировать JSON, и как получить доступ к данным, заблокированным внутри него. В следующей статье мы рассмотрим объектно-ориентированный JavaScript.</p>
+
+<h2 id="Смотрите_также">Смотрите также</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON">JSON object reference page</a></li>
+ <li><a href="/en-US/docs/Web/API/XMLHttpRequest">XMLHttpRequest object reference page</a></li>
+ <li><a href="/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest">Using XMLHttpRequest</a></li>
+ <li><a href="/en-US/docs/Web/HTTP/Methods">HTTP request methods</a></li>
+ <li><a href="http://json.org">Official JSON web site with link to ECMA standard</a></li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects/Object_building_practice", "Learn/JavaScript/Objects")}}</p>
+
+<h2 id="В_этом_модуле">В этом модуле</h2>
+
+<ul>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B/%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D1%8B">Основы объекта</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B/Object-oriented_JS">Объектно-ориентированный JavaScript для начинающих</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B/Object_prototypes">Прототипы объектов</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B/Inheritance">Наследование в JavaScript</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B/JSON">Работа с данными JSON</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B/Object_building_practice">Практика построения объектов</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B/Adding_bouncing_balls_features">Добавление функций в нашу демонстрацию прыгающих шаров</a></li>
+</ul>
+
+<div class="s3gt_translate_tooltip_mini_box" id="s3gt_translate_tooltip_mini" style="background: initial !important; border: initial !important; border-radius: initial !important; border-collapse: initial !important; direction: ltr !important; font-weight: initial !important; height: initial !important; letter-spacing: initial !important; max-width: initial !important; min-height: initial !important; margin: auto !important; outline: initial !important; padding: initial !important; position: absolute; text-align: initial !important; text-shadow: initial !important; width: initial !important; display: initial !important; color: inherit !important; font-size: 13px !important; font-family: X-LocaleSpecific, sans-serif, Tahoma, Helvetica !important; line-height: 13px !important; vertical-align: top !important; white-space: inherit !important; left: 124px; top: 1171px; opacity: 0;">
+<div class="s3gt_translate_tooltip_mini" id="s3gt_translate_tooltip_mini_logo" style="width: 12px; height: 12px; border-radius: 4px;" title="Перевести выделенный фрагмент"></div>
+
+<div class="s3gt_translate_tooltip_mini" id="s3gt_translate_tooltip_mini_sound" style="width: 12px; height: 12px; border-radius: 4px;" title="Прослушать"></div>
+
+<div class="s3gt_translate_tooltip_mini" id="s3gt_translate_tooltip_mini_copy" style="width: 12px; height: 12px; border-radius: 4px;" title="Скопировать текст в буфер обмена"></div>
+</div>
diff --git a/files/ru/learn/javascript/объекты/object-oriented_js/index.html b/files/ru/learn/javascript/объекты/object-oriented_js/index.html
new file mode 100644
index 0000000000..0299268a90
--- /dev/null
+++ b/files/ru/learn/javascript/объекты/object-oriented_js/index.html
@@ -0,0 +1,286 @@
+---
+title: Объектно-ориентированный JavaScript для начинающих
+slug: Learn/JavaScript/Объекты/Object-oriented_JS
+tags:
+ - Constructor
+ - Create
+ - JavaScript
+ - OOJS
+ - Object
+ - Новичку
+ - ООП
+ - экземпляр
+translation_of: Learn/JavaScript/Objects/Object-oriented_JS
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Objects/Basics", "Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects")}}</div>
+
+<p class="summary">Разобравшись с основами, сосредоточимся на объектно-ориентированном JavaScript (OOJS) — данная статья дает базовое представление о теории объектно-ориентированного программирования (ООП), далее рассмотрено как JavaScript эмулирует классы объектов с помощью функции-конструктора и как создаются экземпляры объектов.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Необходимые знания:</th>
+ <td>
+ <p class="brush: html">Базовая компьютерная грамотность, базовое понимание HTML и CSS, знакомство с основами JavaScript (см. <a href="/en-US/docs/Learn/JavaScript/First_steps">Первые шаги</a> и <a href="/en-US/docs/Learn/JavaScript/Building_blocks">C</a>труктурные элементы JavaScript) и основы OOJS (см. <a href="/en-US/docs/Learn/JavaScript/Object-oriented/Introduction">Введение в объекты</a>).</p>
+ </td>
+ </tr>
+ <tr>
+ <th scope="row">Цель:</th>
+ <td>Понять основную теорию объектно-ориентированного программирования, как это относится к JavaScript («все является объектом») и как создавать конструкторы и экземпляры объектов.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Объектно-ориентированное_программирование_основы">Объектно-ориентированное программирование: основы</h2>
+
+<p>Начнём с упрощённого высокоуровневого представления о том, что такое <em>объектно-ориентированное программирование</em> <em>(ООП)</em>. Мы говорим упрощённого, потому что ООП может быстро стать очень сложным, и если сейчас дать полный курс, вероятно, можно запутать больше, чем помочь. Основная идея ООП заключается в том, что мы используем объекты для отображения моделей из реального мира в наших программах и/или упрощения доступа к функциям, которые в противном случае было бы трудно или невозможно использовать.</p>
+
+<p>Объекты могут содержать данные и код, представляющие информацию о том, что вы пытаетесь смоделировать, а также о том, какие у этих объектов должны быть функциональные возможности или поведение. Данные объекта (а часто так же и функции) могут быть точно сохранены (официальный термин "<strong>инкапсулированы"</strong>) внутри пакета объекта, упрощая структуру и доступ к ним. Пакету объекта может быть присвоено определенное имя, на которое можно сослаться и которое иногда называют <strong>пространством имен.</strong> Объекты также широко используются в качестве хранилищ данных, которые могут быть легко отправлены по сети.</p>
+
+<h3 id="Определение_шаблона_объекта">Определение шаблона объекта</h3>
+
+<p>Рассмотрим простую программу, которая отображает информацию об учениках и учителях в школе. Здесь мы рассмотрим теорию ООП в целом, а не в контексте какого-либо конкретного языка программирования.</p>
+
+<p>Вернёмся к объекту Person из нашей статьи <a href="/ru/docs/Learn/JavaScript/Объекты/Основы">Основы объектов</a>, который определяет общие сведения и функциональные возможности человека. Есть много вещей, которые вы <em>можете</em> узнать о человеке (его адрес, рост, размер обуви, профиль ДНК, номер паспорта, значимые черты личности ...), но в данном случае нас интересует только имя, возраст, пол и интересы, а также мы хотим иметь возможность написать краткую информацию о нём, основываясь на этих данных, и сделать так, чтобы он поздоровался. Это известно как <strong>абстракция</strong> — создание простой модели более сложной сущности, которая представляет её наиболее важные аспекты таким образом, чтобы с ней было удобно работать для выполнения целей нашей программы.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13889/person-diagram.png" style="display: block; height: 219px; margin: 0px auto; width: 610px;"></p>
+
+<p>В некоторых языках ООП, это общее определение типа объекта называется <strong>class</strong> (JavaScript использует другой механизм и терминологию, как вы увидите ниже) — это на самом деле не объект, а шаблон, который определяет, какие характеристики должен иметь объект.</p>
+
+<h3 id="Создание_реальных_объектов">Создание реальных объектов</h3>
+
+<p>Из нашего класса мы можем создать <strong>экземпляры объектов</strong> — объекты, содержащие данные и функциональные возможности, определённые в классе. Из нашего класса Person мы теперь можем создавать модели реальных людей:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13883/MDN-Graphics-instantiation-2.png" style="display: block; height: 743px; margin: 0px auto; width: 700px;"></p>
+
+<p>Когда экземпляр объекта создается из класса, для его создания выполняется <strong>функция-конструктор </strong>класса. Этот процесс создания экземпляра объекта из класса называется <strong>создание экземпляра (instantiation)</strong> — из класса <strong>создается</strong> экземпляр объекта.</p>
+
+<h3 id="Специализированные_классы">Специализированные классы</h3>
+
+<p>В нашем случае нам не нужны все люди — нам требуются учителя и ученики, которые являются более конкретными типами людей. В ООП мы можем создавать новые классы на основе других классов — эти новые <strong>дочерние классы</strong> могут быть созданы для <strong>наследования</strong> данных и характеристик <strong>родительского класса</strong>, так чтобы можно было использовать функциональные возможности, общие для всех типов объекта, вместо того чтобы дублировать их. Когда функциональность различается между классами, можно по мере необходимости определять специализированные функции непосредственно на них.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13881/MDN-Graphics-inherited-3.png" style="display: block; height: 743px; margin: 0px auto; width: 700px;"></p>
+
+<p>Это действительно полезно — преподаватели и студенты имеют много общих характеристик, таких как имя, пол и возраст, и удобно определить их только один раз. Вы можете также задать одну и ту же характеристику отдельно в разных классах, поскольку каждое определение этой характеристики будет находиться в отдельном пространстве имен. Например, приветствие студента может быть в форме "Yo, I'm [firstName]" (например <em>Yo, I'm Sam</em>), в то время как учитель может использовать что-то более формальное, такое как "Hello, my name is [Prefix] [lastName], and I teach [Subject]." (например <em>Hello, My name is Mr Griffiths, and I teach Chemistry</em>).</p>
+
+<div class="note">
+<p><strong>Примечание</strong>: Если вам интересно, существует специальный термин <strong>Polymorphism (Полиморфизм)</strong> - это забавное слово, обозначающее реализацию той же функциональности для нескольких типов объекта. </p>
+</div>
+
+<p>Теперь вы можете создавать экземпляры объекта из дочерних классов. Например:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13885/MDN-Graphics-instantiation-teacher-3.png" style="display: block; height: 743px; margin: 0px auto; width: 700px;"></p>
+
+<p>Далее мы рассмотрим, как ООП теорию можно применить на практике в JavaScript.</p>
+
+<h2 id="Конструкторы_и_экземпляры_объектов">Конструкторы и экземпляры объектов</h2>
+
+<p>JavaScript использует специальные функции, называемые функциями конструктора (<strong>constructor functions</strong>) для определения объектов и их свойств. Они полезны, потому что вы часто будете сталкиваться с ситуациями, в которых не известно, сколько объектов вы будете создавать; конструкторы позволяют создать столько объектов, сколько нужно эффективным способом, прикреплением данных и функций для объектов по мере необходимости.</p>
+
+<p>Рассмотрим создание классов через конструкторы и создание экземпляров объектов из них в JavaScript. Прежде всего, мы хотели бы, чтобы вы создали новую локальную копию файла <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs.html">oojs.html</a>, который мы видели в нашей первой статье «Объекты».</p>
+
+<h3 id="Простой_пример">Простой пример</h3>
+
+<ol>
+ <li>Давайте рассмотрим как можно определить человека с нормальной функцией. Добавьте эту функцию в элемент <code>script</code>:
+
+ <pre class="brush: js notranslate">function createNewPerson(name) {
+ const obj = {};
+ obj.name = name;
+ obj.greeting = function() {
+ alert('Hi! I\'m ' + this.name + '.');
+ };
+ return obj;
+}</pre>
+ </li>
+ <li>Теперь вы можете создать нового человека, вызвав эту функцию - попробуйте следующие строки в консоли JavaScript браузера:
+ <pre class="brush: js notranslate">const salva = createNewPerson('Salva');
+salva.name;
+salva.greeting();</pre>
+ Это работает достаточно хорошо, но код излишне многословен; если мы знаем, что хотим создать объект, зачем нам явно создавать новый пустой объект и возвращать его? К счастью, JavaScript предоставляет нам удобный способ в виде функций-конструкторов - давайте сделаем это сейчас!</li>
+ <li>Замените предыдущую функцию следующей:
+ <pre class="brush: js notranslate">function Person(name) {
+ this.name = name;
+ this.greeting = function() {
+ alert('Hi! I\'m ' + this.name + '.');
+ };
+}</pre>
+ </li>
+</ol>
+
+<p>Функция-конструктор - это JavaScript версия класса. Вы заметите, что в нем есть все признаки, которые вы ожидаете от функции, хотя он ничего не возвращает и явно не создает объект - он в основном просто определяет свойства и методы. Вы также увидите, что ключевое слово this также используется здесь, - это в основном говорит о том, что всякий раз, когда создается один из этих экземпляров объектов, свойство имени объекта будет равно значению <code>name</code>, переданному вызову конструктора, и метод <code>greeting()</code> будет использовать значение имени, переданное также вызову конструктора.</p>
+
+<div class="note">
+<p><strong>Примечание:</strong> Имя функции конструктора обычно начинается с заглавной буквы - это соглашение используется для упрощения распознавания функций конструктора в коде.</p>
+</div>
+
+<p>Итак, как мы вызываем конструктор для создания некоторых объектов?</p>
+
+<ol>
+ <li>Добавьте следующие строки под предыдущим добавлением кода:
+ <pre class="brush: js notranslate">let person1 = new Person('Bob');
+let person2 = new Person('Sarah');</pre>
+ </li>
+ <li>Сохраните код и перезагрузите его в браузере и попробуйте ввести следующие строки в консоль JS:
+ <pre class="brush: js notranslate">person1.name
+person1.greeting()
+person2.name
+person2.greeting()</pre>
+ </li>
+</ol>
+
+<p>Круто! Теперь, как вы видите, у нас есть два новых объекта на странице, каждый из которых хранится в отдельном пространстве имен - при доступе к их свойствам и методам вы должны начинать вызовы с <code>person1</code> или <code>person2</code>; функциональность, содержащаяся внутри, аккуратно упакована, поэтому она не будет конфликтовать с другими функциями. Тем не менее, у них есть одно и то же свойство <code>name</code> и <code>greeting()</code>. Обратите внимание, что они используют свое собственное значение <code>name</code>, которое было присвоено им, когда они были созданы; это одна из причин, почему очень важно использовать <code>this</code>, таким образом они будут использовать свои собственные значения, а не какие-либо другие.</p>
+
+<p>Давайте снова посмотрим на вызовы конструктора:</p>
+
+<pre class="brush: js notranslate">let person1 = new Person('Bob');
+let person2 = new Person('Sarah');</pre>
+
+<p>В каждом случае ключевое слово <code>new</code> используется, чтобы сообщить браузеру, что мы хотим создать экземпляр нового объекта, за которым следует имя функции с ее необходимыми параметрами, содержащимися в круглых скобках, и результат сохраняется в переменной - очень похоже на то, как вызывается стандартная функция. Каждый экземпляр создается в соответствии с этим определением:</p>
+
+<pre class="brush: js notranslate">function Person(name) {
+ this.name = name;
+ this.greeting = function() {
+ alert('Hi! I\'m ' + this.name + '.');
+ };
+}</pre>
+
+<p>После создания новых объектов переменные <code>person1</code> и <code>person2</code> содержат следующие объекты:</p>
+
+<pre class="brush: js notranslate">{
+ name: 'Bob',
+ greeting: function() {
+ alert('Hi! I\'m ' + this.name + '.');
+ }
+}
+
+{
+ name: 'Sarah',
+ greeting: function() {
+ alert('Hi! I\'m ' + this.name + '.');
+ }
+}</pre>
+
+<p>Обратите внимание, что когда мы вызываем нашу функцию-конструктор, мы определяем <code>greeting()</code> каждый раз, что не является идеальным. Чтобы этого избежать, вместо этого мы можем определить функции на прототипе, о которых мы поговорим позже.</p>
+
+<h3 id="Создавая_наш_готовый_конструктор">Создавая наш готовый конструктор</h3>
+
+<p>Пример, рассмотренный выше, был лишь наглядным примером, чтобы вы поняли суть. Теперь, давайте создадим нашу конечную функцию-конструктор <code>Person()</code>.</p>
+
+<ol>
+ <li>Замените весь предыдущий код новой функцией конструктора - это, в принципе, тот же самое что и в наглядном примере, но несколько сложнее:
+ <pre class="brush: js notranslate">function Person(first, last, age, gender, interests) {
+ this.name = {
+ first : first,
+ last: last
+ };
+ this.age = age;
+ this.gender = gender;
+ this.interests = interests;
+ this.bio = function() {
+ alert(this.name.first + ' ' + this.name.last + ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.');
+ };
+ this.greeting = function() {
+ alert('Hi! I\'m ' + this.name.first + '.');
+ };
+};</pre>
+ </li>
+ <li>Теперь добавьте следующую строку ниже, чтобы создать экземпляр объекта из него:
+ <pre class="brush: js notranslate">let person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']);</pre>
+ </li>
+</ol>
+
+<p>Как вы могли заметить, вы можете получить доступ к свойствам и методам, как это было ранее, - попробуйте использовать их в консоли JS:</p>
+
+<pre class="brush: js notranslate">person1['age']
+person1.interests[1]
+person1.bio()
+// etc.</pre>
+
+<div class="note"><strong>Примечание</strong>: Если у Вас возникли проблемы с работой кода, попробуйте сравнить его с нашей версией - см. <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-class-finished.html">oojs-class-finished.html</a> (также смотрите, как он работает <a href="https://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-class-finished.html">в прямом эфире</a>).</div>
+
+<h3 id="Дальнейшие_упражнения">Дальнейшие упражнения</h3>
+
+<p>Для начала, попробуйте добавить еще пару собственных строк создания объекта и попробуйте получить и установить элементы полученных экземпляров объектов.</p>
+
+<p>Кроме того, есть несколько проблем с нашим методом <code>bio()</code> - вывод всегда включает местоимение «He» ("Он" в пер. с англ.), даже если ваш человек является женщиной или какой-либо другой предпочтительной гендерной классификацией. И <code>bio</code> будет включать только два интереса, даже если в массиве <code>interests</code> указано больше. Можете ли Вы решить, как исправить это в определении класса (конструкторе)? Вы можете поместить любой код, который вам нравится внутри конструктора (вам, вероятно, понадобятся несколько условий и цикл). Подумайте о том, как предложения должны быть структурированы по-разному в зависимости от пола и в зависимости от того, имеет ли число перечисленных интересов 1, 2 или более 2.</p>
+
+<div class="note">
+<p><strong>Примечание</strong>: Если у Вас возникли трудности с решением задачи, мы предоставили <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-class-further-exercises.html">ответ в нашем репозитории GitHub</a> (<a href="http://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-class-further-exercises.html">см. это в действии</a>) — но сначала попробуйте написать сами!</p>
+</div>
+
+<h2 id="Другие_способы_создания_экземпляров_объектов">Другие способы создания экземпляров объектов</h2>
+
+<p>До сих пор мы видели два разных способа создания экземпляра объекта - <a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics#Object_basics">объявление объектного литерала</a> и использование функции конструктора (см. выше).</p>
+
+<p>Это имеет смысл, но есть и другие способы - мы бы хотели ознакомить Вас с ними на случай, если Вы встретите их в своих путешествиях по Сети.</p>
+
+<h3 id="Конструктор_Object">Конструктор Object ()</h3>
+
+<p>Прежде всего, вы можете использовать конструктор <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object">Object()</a></code> для создания нового объекта. Да, даже общие объекты имеют конструктор, который генерирует пустой объект.</p>
+
+<ol>
+ <li>Попробуйте ввести это в консоль JavaScript вашего браузера:
+ <pre class="brush: js notranslate">let person1 = new Object();</pre>
+ </li>
+ <li>Это сохраняет ссылку на пустой объект в переменную <code>person1</code>. Затем вы можете добавить свойства и методы к этому объекту с использованием точечной или скобочной нотации по желанию; попробуйте эти примеры в консоли:
+ <pre class="brush: js notranslate">person1.name = 'Chris';
+person1['age'] = 38;
+person1.greeting = function() {
+ alert('Hi! I\'m ' + this.name + '.');
+};</pre>
+ </li>
+ <li>Вы также можете передать литерал объекта конструктору <code>Object()</code> в качестве параметра, чтобы заполнить его свойствами / методами. Попробуйте это в консоли JS:
+ <pre class="brush: js notranslate">let person1 = new Object({
+ name: 'Chris',
+ age: 38,
+ greeting: function() {
+ alert('Hi! I\'m ' + this.name + '.');
+ }
+});</pre>
+ </li>
+</ol>
+
+<h3 id="Использование_метода_create">Использование метода create()</h3>
+
+<p>Конструкторы могут помочь вам определить порядок кода - вы можете создать конструктор в одном месте, а затем создавать экземпляры по мере необходимости, и их происхождение будет понятным.</p>
+
+<p>Однако некоторые люди предпочитают создавать экземпляры объектов без предварительного создания конструкторов, особенно если они создают только несколько экземпляров объекта. JavaScript имеет встроенный метод <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create">create()</a></code>, который позволяет вам это делать. С его помощью вы можете создать новый объект на основе любого существующего объекта.</p>
+
+<ol>
+ <li>Закончив упражнение из предыдущего раздела, загруженное в браузер, попробуйте это в консоли JavaScript:
+ <pre class="brush: js notranslate">let person2 = Object.create(person1);</pre>
+ </li>
+ <li>Теперь попробуйте:
+ <pre class="brush: js notranslate">person2.name
+person2.greeting()</pre>
+ </li>
+</ol>
+
+<p>Вы увидите, что <code>person2</code> был создан на основе <code>person1</code> - он имеет те же свойства и метод, доступные для него.</p>
+
+<p>Одно ограничение метода <code>create()</code> заключается в том, что IE8 не поддерживает его. Поэтому конструкторы могут быть более эффективными, если вы хотите поддерживать старые браузеры.</p>
+
+<p>Подробнее мы рассмотрим особенности метода <code>create()</code> немного позже.</p>
+
+<h2 id="Сводка">Сводка</h2>
+
+<p>В этой статье представлен упрощенный взгляд на объектно-ориентированную теорию — это еще не вся история, но она дает представление о том, с чем мы имеем дело. Кроме того, мы начали рассматривать различные способы создания экземпляров объектов.</p>
+
+<p>В следующей статье мы рассмотрим прототипы объектов JavaScript.</p>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Basics", "Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects")}}</p>
+
+<h2 id="В_этом_модуле">В этом модуле</h2>
+
+<ul>
+ <li><a href="/ru/docs/Learn/JavaScript/Объекты/Основы">Основы объекта</a></li>
+ <li><a href="/ru/docs/Learn/JavaScript/Объекты/Object-oriented_JS">Объектно-ориентированный JavaScript для начинающих</a></li>
+ <li><a href="/ru/docs/Learn/JavaScript/Объекты/Object_prototypes">Прототипы объектов</a></li>
+ <li><a href="/ru/docs/Learn/JavaScript/Объекты/Inheritance">Наследование в JavaScript</a></li>
+ <li><a href="/ru/docs/Learn/JavaScript/Объекты/JSON">Работа с данными JSON</a></li>
+ <li><a href="/ru/docs/Learn/JavaScript/Объекты/Object_building_practice">Практика построения объектов</a></li>
+ <li><a href="/ru/docs/Learn/JavaScript/Объекты/Adding_bouncing_balls_features">Добавление функций в нашу демонстрацию прыгающих шаров</a></li>
+</ul>
diff --git a/files/ru/learn/javascript/объекты/object_building_practice/index.html b/files/ru/learn/javascript/объекты/object_building_practice/index.html
new file mode 100644
index 0000000000..b06b769ca4
--- /dev/null
+++ b/files/ru/learn/javascript/объекты/object_building_practice/index.html
@@ -0,0 +1,302 @@
+---
+title: Практика построения объектов
+slug: Learn/JavaScript/Объекты/Object_building_practice
+tags:
+ - Guide
+ - JavaScript
+translation_of: Learn/JavaScript/Objects/Object_building_practice
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects/Adding_bouncing_balls_features", "Learn/JavaScript/Objects")}}</div>
+
+<p class="summary">В предыдущих статьях мы рассмотрели всю существенную теорию объектов JavaScript и детали синтаксиса, давая вам прочную основу для начала. В этой статье мы погружаемся в практическое упражнение, давая вам больше практики в создании пользовательских объектов JavaScript, с веселым и красочным результатом.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Необходимые знания:</th>
+ <td>Базовая компьютерная грамотность, базовые знания HTML и CSS, знакомство с основами JavaScript (see <a href="/en-US/docs/Learn/JavaScript/First_steps">First steps</a> and <a href="/en-US/docs/Learn/JavaScript/Building_blocks">Building blocks</a>) и основами OOJS (см. <a href="/en-US/docs/Learn/JavaScript/Object-oriented/Introduction">Introduction to objects</a>).</td>
+ </tr>
+ <tr>
+ <th scope="row">Цель:</th>
+ <td>Получение некоторой практики в использовании объектов и объектно-ориентированных методов в реальном мире.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Давайте_подбросим_несколько_мячей">Давайте подбросим несколько мячей</h2>
+
+<p>В этой статье мы напишем классическую демонстрацию «прыгающих шаров», чтобы показать вам, насколько полезными могут быть объекты в JavaScript. Наши маленькие шары будут подпрыгивать на экране и менять цвет, когда они касаются друг друга. Готовый пример будет выглядеть примерно так:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13865/bouncing-balls.png" style="display: block; height: 614px; margin: 0px auto; width: 800px;"></p>
+
+<ol>
+</ol>
+
+<p>В этом примере будет использоваться <a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Drawing_graphics">Canvas API</a> для рисования шаров на экране и API <a href="https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame">requestAnimationFrame</a> для анимации всего экрана - вам не нужно иметь никаких предыдущих знаний об этих API, и мы надеемся, что к тому моменту, когда вы закончите эту статью, вам будет интересно изучить их больше. По пути мы воспользуемся некоторыми изящными объектами и покажем вам пару хороших приемов, таких как отскоки шаров от стен и проверка того, попали ли они друг в друга (иначе известный как <strong>обнаружение столкновения</strong>).</p>
+
+<h2 id="Начало_работы">Начало работы</h2>
+
+<p>Для начала создайте локальные копии наших файлов<code><a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/index.html">index.html</a></code>, <code><a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/style.css">style.css</a></code> и <code><a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/main.js">main.js</a></code>. Они содержат следующее:</p>
+
+<ol>
+ <li>Очень простой HTML-документ, содержащий элемент {{HTMLElement("h1")}}, элемент {{HTMLElement("canvas")}} для рисования наших шаров и элементы для применения нашего CSS и JavaScript в нашем HTML.</li>
+ <li>Некоторые очень простые стили, которые в основном служат для стилизации и позиционирования <code>&lt;h1&gt;</code>, и избавляются от любых полос прокрутки или отступы по краю страницы (так что это выглядит красиво и аккуратно).</li>
+ <li>Некоторые JavaScript, которые служат для настройки элемента <code>&lt;canvas&gt;</code> и предоставляют общую функцию, которую мы собираемся использовать.</li>
+</ol>
+
+<p>Первая часть скрипта выглядит так:</p>
+
+<pre class="brush: js notranslate">var canvas = document.querySelector('canvas');
+
+var ctx = canvas.getContext('2d');
+
+var width = canvas.width = window.innerWidth;
+var height = canvas.height = window.innerHeight;</pre>
+
+<p>Этот скрипт получает ссылку на элемент <code>&lt;canvas&gt;</code>, а затем вызывает метод <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext">getContext()</a></code>, чтобы дать нам контекст, по которому мы можем начать рисовать. Результирующая переменная (ctx) - это объект, который непосредственно представляет область рисования холста и позволяет рисовать на ней 2D-фигуры.</p>
+
+<p>Затем мы устанавливаем переменные, называемые <code>width</code> и <code>height</code>, а также ширину и высоту элемента canvas (представленные свойствами <code>canvas.width</code> и <code>canvas.height</code>), чтобы равняться ширине и высоте окна просмотра браузера (область, на которой отображается веб-страница - это можно получить из свойств {{domxref("Window.innerWidth")}} и {{domxref("Window.innerHeight")}}).</p>
+
+<p>Вы увидите здесь, что мы объединяем несколько назначений вместе, чтобы все переменные были установлены быстрее - это совершенно нормально.</p>
+
+<p>Последний бит исходного скрипта выглядит следующим образом:</p>
+
+<pre class="brush: js notranslate">function random(min, max) {
+ var num = Math.floor(Math.random() * (max - min + 1)) + min;
+ return num;
+}</pre>
+
+<p>Эта функция принимает два числа в качестве аргументов и возвращает случайное число в диапазоне между ними.</p>
+
+<h2 id="Моделирование_мяча_в_нашей_программе">Моделирование мяча в нашей программе</h2>
+
+<p>В нашей программе будет много шаров, подпрыгивающих вокруг экрана. Поскольку эти шары будут вести себя одинаково, имеет смысл представлять их в виде объекта. Начнем с добавления следующего конструктора в конец нашего кода.</p>
+
+<pre class="brush: js notranslate">function Ball(x, y, velX, velY, color, size) {
+  this.x = x;
+  this.y = y;
+  this.velX = velX;
+  this.velY = velY;
+  this.color = color;
+  this.size = size;
+}</pre>
+
+<p>Здесь мы включаем некоторые параметры, которые определяют свойства, которым должен соответствовать каждый шар в нашей программе:</p>
+
+<ul>
+ <li><code>x</code> и <code>y</code> координаты - горизонтальные и вертикальные координаты, где мяч будет запускаться на экране. Координаты могут находиться в диапазоне от 0 (верхний левый угол) до ширины и высоты окна просмотра браузера (нижний правый угол).</li>
+ <li>горизонтальная и вертикальная скорость (<code>velX</code> и <code>velY</code>) - каждому шару задана горизонтальная и вертикальная скорость; в реальном выражении эти значения будут регулярно добавляться к значениям координат <code>x</code>/<code>y</code>, когда мы начнем анимировать шары, чтобы их перемещать на каждом кадре.</li>
+ <li><code>color</code> - каждый мяч получает цвет.</li>
+ <li><code>size</code> - каждый мяч получает размер - это будет его радиус в пикселях.</li>
+</ul>
+
+<p>Этим мы сортируем свойства, но что насчет методов? Мы хотим заставить эти шары на самом деле сделать что-то в нашей программе.</p>
+
+<h3 id="Рисование_шара">Рисование шара</h3>
+
+<p>Сначала добавьте следующий метод <code>draw()</code> к <code>Ball()</code>'s <code>prototype</code>:</p>
+
+<pre class="brush: js notranslate">Ball.prototype.draw = function() {
+ ctx.beginPath();
+ ctx.fillStyle = this.color;
+ ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI);
+ ctx.fill();
+}</pre>
+
+<p>Используя эту функцию, мы можем сказать нашему шару нарисовать себя на экране, вызвав ряд членов контекста двумерного холста, который мы определили ранее (<code>ctx</code>). Контекст похож на бумагу, и теперь мы хотим, чтобы наше перо рисовало что-то на нем:</p>
+
+<ul>
+ <li>Во-первых, мы используем <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/beginPath">beginPath()</a></code>, чтобы указать, что мы хотим нарисовать фигуру на бумаге.</li>
+ <li>Затем мы используем <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle">fillStyle</a></code> для определения того, какой цвет нам нужен, - мы устанавливаем его в свойство цвета нашего шара.</li>
+ <li>Затем мы используем метод <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/arc">arc()</a></code> для отслеживания формы дуги на бумаге. Его параметры:
+ <ul>
+ <li>Положение <code>x</code> и <code>y</code> центра дуги - мы указываем свойства <code>x</code> и <code>y</code> нашего шара.</li>
+ <li>Радиус нашей дуги - мы указываем свойство <code>size</code> шарика.</li>
+ <li>Последние два параметра определяют начальное и конечное число градусов по кругу, по которому проходит дуга. Здесь мы указываем 0 градусов и <code>2 * PI</code>, что эквивалентно 360 градусам в радианах (досадно, вы должны указать это в радианах). Это дает нам полный круг. Если вы указали только <code>1 * PI</code>, вы получите полукруг (180 градусов).</li>
+ </ul>
+ </li>
+ <li>В последнем случае мы используем метод <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fill">fill()</a></code>, который в основном утверждает: «Закончите рисование пути, начатого с <code>beginPath()</code>, и заполните область, которую он занимает с цветом, указанным ранее в <code>fillStyle</code>».</li>
+</ul>
+
+<p>Теперь вы можете начать тестирование своего объекта..</p>
+
+<ol>
+ <li>Сохраните код и загрузите HTML-файл в браузер.</li>
+ <li>Откройте консоль JavaScript браузера, а затем обновите страницу, чтобы размер холста изменился в соответствии с новой шириной и высотой окна просмотра браузера после открытия консоли.</li>
+ <li>Чтобы создать новый экземпляр шара, введите следующее:
+ <pre class="brush: js notranslate">var testBall = new Ball(50, 100, 4, 4, 'blue', 10);</pre>
+ </li>
+ <li>Попробуйте вызвать его свойства и методы:
+ <pre class="brush: js notranslate">testBall.x
+testBall.size
+testBall.color
+testBall.draw()</pre>
+ </li>
+ <li>После введения последней строки, вы должны увидеть, как мяч нарисовался где-то на вашем холсте.</li>
+</ol>
+
+<h3 id="Обновление_данных_мяча">Обновление данных мяча</h3>
+
+<p>Мы можем нарисовать мяч в нужном положении, но чтобы начать движение мяча, нам нужна функция обновления. Добавьте следующий код внизу вашего файла JavaScript, чтобы добавить метод <code>update()</code> к <code>Ball()</code>'s <code>prototype</code>:</p>
+
+<pre class="brush: js notranslate">Ball.prototype.update = function() {
+ if ((this.x + this.size) &gt;= width) {
+ this.velX = -(this.velX);
+ }
+
+ if ((this.x - this.size) &lt;= 0) {
+ this.velX = -(this.velX);
+ }
+
+ if ((this.y + this.size) &gt;= height) {
+ this.velY = -(this.velY);
+ }
+
+ if ((this.y - this.size) &lt;= 0) {
+ this.velY = -(this.velY);
+ }
+
+ this.x += this.velX;
+ this.y += this.velY;
+}</pre>
+
+<p>Первые четыре части функции проверяют, достиг ли шар края холста. Если это так, мы изменяем полярность соответствующей скорости, чтобы заставить шар двигаться в противоположном направлении. Так, например, если мяч двигался вверх (положительный <code>velY</code>), то вертикальная скорость изменяется так, что он начинает двигаться вниз (отрицательная величина <code>velY</code>).</p>
+
+<p>В этих четырех случаях мы:</p>
+
+<ul>
+ <li>Проверяем больше ли координата <code>x</code>, чем ширина холста (мяч уходит с правого края).</li>
+ <li>Проверяем будет ли координата <code>x</code> меньше 0 (мяч уходит с левого края).</li>
+ <li>Проверяем будет ли координата <code>y</code> больше высоты холста (мяч уходит с нижнего края).</li>
+ <li>Проверяем будет ли координата <code>y</code> меньше 0 (мяч уходит с верхнего края).</li>
+</ul>
+
+<p>В каждом случае мы включаем <code>size</code> шарика в расчет, потому что координаты <code>x</code>/<code>y</code> находятся в центре шара, но мы хотим, чтобы край шара отскакивал от периметра - мы не хотим, чтобы мяч на половину заходил за границу экрана прежде чем он начнет возвращаться назад.</p>
+
+<p>Последние две строки добавляют значение <code>velX</code> к координате <code>x</code>, а значение <code>velY</code> - координате <code>y</code> - шар фактически перемещается при каждом вызове этого метода.</p>
+
+<p>На сейчас этого достаточно, давайте продолжим анимацию!</p>
+
+<h2 id="Анимация_мяча">Анимация мяча</h2>
+
+<p>Теперь давайте приступать к веселью! Сейчас мы начнем добавлять шары к холсту и анимировать их.</p>
+
+<ol>
+ <li>Во-первых, нам нужно где-то хранить все наши шары. Следующий массив выполнит это задание - добавьте его внизу кода:
+ <pre class="brush: js notranslate">var balls = [];</pre>
+
+ <p>Все программы, которые оживляют вещи, обычно включают цикл анимации, который служит для обновления информации в программе, а затем визуализации результирующего представления для каждого кадра анимации; это основа для большинства игр и других подобных программ.</p>
+ </li>
+ <li>Добавьте ниже эту часть кода:
+ <pre class="brush: js notranslate">function loop() {
+ ctx.fillStyle = 'rgba(0, 0, 0, 0.25)';
+ ctx.fillRect(0, 0, width, height);
+
+ while (balls.length &lt; 25) {
+    var ball = new Ball(
+      random(0,width),
+      random(0,height),
+      random(-7,7),
+      random(-7,7),
+      'rgb(' + random(0,255) + ',' + random(0,255) + ',' + random(0,255) +')',
+      random(10,20)
+    );
+ balls.push(ball);
+ }
+
+ for (var i = 0; i &lt; balls.length; i++) {
+ balls[i].draw();
+ balls[i].update();
+ }
+
+ requestAnimationFrame(loop);
+}</pre>
+
+ <p>Наша функция <code>loop()</code> выполняет следующие действия:</p>
+
+ <ul>
+ <li>Устанавливает цвет заливки на полупрозрачный черный, затем рисует прямоугольник цвета по всей ширине и высоте холста, используя <code>fillRect()</code> (четыре параметра обеспечивают начальную координату, а ширину и высоту для рисованного прямоугольника ). Это позволяет скрыть рисунок предыдущего кадра до того, как будет нарисован следующий. Если вы этого не сделаете, вы увидите, как длинные змеи пробираются вокруг холста, а не шары! Цвет заливки устанавливается на полупрозрачный, <code>rgba(0,0,0,0,25)</code>, чтобы позволить нескольким кадрам слегка просвечивать, создавая маленькие тропы за шариками по мере их перемещения. Если вы изменили 0.25 на 1, вы больше не увидите их. Попробуйте изменить это число, чтобы увидеть эффект, который он имеет.</li>
+ <li>Создает новый экземпляр нашего <code>Ball()</code>, используя случайные значения, сгенерированные с помощью нашей функции <code>random()</code>, затем <code>push()</code> на конец нашего массива шаров, но только в том случае, когда количество шаров в массиве меньше 25. Итак когда у нас есть 25 мячей на экране, больше не появляется шаров. Вы можете попробовать изменить число в <code>balls.length &lt; 25</code>, чтобы получить больше или меньше шаров на экране. В зависимости от того, сколько вычислительной мощности имеет ваш компьютер / браузер, если указать несколько тысячь шаров, это может довольно существенно повлиять на производительность анимации. </li>
+ <li>перебирает все шары в массиве <code>balls</code> и запускает каждую функцию <code>draw()</code> и <code>update()</code> для рисования каждого из них на экране, а затем выполняет необходимые обновления по положению и скорости во времени для следующего кадра.</li>
+ <li>Выполняет функцию снова с помощью метода <code>requestAnimationFrame()</code> - когда этот метод постоянно запускается и передается одно и то же имя функции, он будет запускать эту функцию определенное количество раз в секунду для создания плавной анимации. Обычно это делается рекурсивно - это означает, что функция вызывает себя каждый раз, когда она запускается, поэтому она будет работать снова и снова.</li>
+ </ul>
+ </li>
+ <li>И последнее, но не менее важное: добавьте следующую строку в конец вашего кода - нам нужно вызвать функцию один раз, чтобы начать анимацию.
+ <pre class="brush: js notranslate">loop();</pre>
+ </li>
+</ol>
+
+<p>Вот и все для основы - попробуйте сохранить и освежить, чтобы проверить свои прыгающие шары!</p>
+
+<h2 id="Добавление_обнаружения_столкновений">Добавление обнаружения столкновений</h2>
+
+<p>Теперь немного поиграем, давайте добавим в нашу программу обнаружение конфликтов, поэтому наши мячи узнают, когда они ударят по другому шару.</p>
+
+<ol>
+ <li>Прежде всего, добавьте следующее определение метода ниже, где вы определили метод <code>update()</code> (т.е. блок <code>Ball.prototype.update</code>).
+
+ <pre class="brush: js notranslate">Ball.prototype.collisionDetect = function() {
+ for (var j = 0; j &lt; balls.length; j++) {
+ if (!(this === balls[j])) {
+ var dx = this.x - balls[j].x;
+ var dy = this.y - balls[j].y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+
+ if (distance &lt; this.size + balls[j].size) {
+ balls[j].color = this.color = 'rgb(' + random(0, 255) + ',' + random(0, 255) + ',' + random(0, 255) +')';
+ }
+ }
+ }
+}</pre>
+
+ <p>Этот метод немного сложный, поэтому не беспокойтесь, если вы не понимаете, как именно это работает. Ниже приводится объяснение:</p>
+
+ <ul>
+ <li>Для каждого шара нам нужно проверить каждый другой шар, чтобы увидеть, столкнулся ли он с текущим мячом. Чтобы сделать это, мы открываем еще один цикл <code>for</code>  через все шары в массиве <code>balls[]</code>.</li>
+ <li>Сразу же в нашем цикле for мы используем оператор <code>if</code>, чтобы проверить, проходит ли текущий шарик, тот же самый шар, что и тот, который мы сейчас проверяем. Мы не хотим проверять, что мяч столкнулся с самим собой! Для этого мы проверяем, является ли текущий мяч (т.е. мяч, метод которого вызван методом collisionDetect) такой же, как шар петли (т.е. шар, на который ссылается текущая итерация цикла for в collisionDetect метод). Затем мы используем <code>!</code> чтобы отменить проверку, чтобы код внутри оператора if выполнялся только в том случае, если они <strong>не</strong> совпадают.</li>
+ <li>Затем мы используем общий алгоритм для проверки столкновения двух окружностей. Мы в основном проверяем, перекрывается ли какая-либо из областей круга. Это объясняется далее <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/2D_collision_detection">2D collision detection</a>.</li>
+ <li>Если обнаружено столкновение, выполняется код внутри внутреннего оператора <code>if</code>. В этом случае мы просто устанавливаем свойство <code>color</code> обоих кругов на новый случайный цвет. Мы могли бы сделать что-то гораздо более сложное, например, заставить шары отскакивать друг от друга реалистично, но это было бы гораздо сложнее реализовать. Для такого моделирования физики разработчики склонны использовать игры или библиотеку физики, такие как <a href="http://wellcaffeinated.net/PhysicsJS/">PhysicsJS</a>, <a href="http://brm.io/matter-js/">matter.js</a>, <a href="http://phaser.io/">Phaser</a> и т.д.</li>
+ </ul>
+ </li>
+ <li>Вы также должны вызвать этот метод в каждом кадре анимации. Добавьте следующий код после строки <code>balls[i].update();</code>
+ <pre class="brush: js notranslate">balls[i].collisionDetect();</pre>
+ </li>
+ <li>Сохраните и обновите демо снова, и вы увидите, как ваши мячи меняют цвет, когда они сталкиваются!</li>
+</ol>
+
+<div class="note">
+<p><strong>Примечание</strong>. Если вам не удается заставить этот пример работать, попробуйте сравнить код JavaScript с нашей <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/main-finished.js">готовой версией</a> (также смотрите, как он работает <a href="https://mdn.github.io/learning-area/javascript/oojs/bouncing-balls/index-finished.html">в прямом эфире</a>).</p>
+</div>
+
+<h2 id="Резюме">Резюме</h2>
+
+<p>Мы надеемся, что вам понравилось писать собственный пример случайных прыгающих шаров в реальном мире, используя различные объектные и объектно-ориентированные методы из всего модуля! Это должно было дать вам некоторую полезную практику использования объектов и хорошего контекста реального мира.</p>
+
+<p>Вот и все для предметных статей - все, что осталось сейчас, - это проверить свои навыки в оценке объекта.</p>
+
+<h2 id="Смотрите_также">Смотрите также</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Web/API/Canvas_API/Tutorial">Canvas tutorial</a> — руководство для новичков по использованию 2D-холста.</li>
+ <li><a href="/en-US/docs/Web/API/window/requestAnimationFrame">requestAnimationFrame()</a></li>
+ <li><a href="/en-US/docs/Games/Techniques/2D_collision_detection">2D collision detection</a></li>
+ <li><a href="/en-US/docs/Games/Techniques/3D_collision_detection">3D collision detection</a></li>
+ <li><a href="/en-US/docs/Games/Tutorials/2D_Breakout_game_pure_JavaScript">2D breakout game using pure JavaScript</a> — a great beginner's tutorial showing how to build a 2D game.</li>
+ <li><a href="/en-US/docs/Games/Tutorials/2D_breakout_game_Phaser">2D breakout game using Phaser</a> — explains the basics of building a 2D game using a JavaScript game library.</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects/Adding_bouncing_balls_features", "Learn/JavaScript/Objects")}}</p>
+
+<h2 id="В_этом_модуле">В этом модуле</h2>
+
+<ul>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B/%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D1%8B">Основы объекта</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B/Object-oriented_JS">Объектно-ориентированный JavaScript для начинающих</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B/Object_prototypes">Прототипы объектов</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B/Inheritance">Наследование в JavaScript</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B/JSON">Работа с данными JSON</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B/Object_building_practice">Практика построения объектов</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B/Adding_bouncing_balls_features">Добавление функций в нашу демонстрацию прыгающих шаров</a></li>
+</ul>
diff --git a/files/ru/learn/javascript/объекты/object_prototypes/index.html b/files/ru/learn/javascript/объекты/object_prototypes/index.html
new file mode 100644
index 0000000000..0a76580d9c
--- /dev/null
+++ b/files/ru/learn/javascript/объекты/object_prototypes/index.html
@@ -0,0 +1,285 @@
+---
+title: Прототипы объектов
+slug: Learn/JavaScript/Объекты/Object_prototypes
+tags:
+ - JavaScript
+ - create()
+ - Конструктор
+ - Начинающий
+ - ООП
+ - Обучение
+ - Обьект
+ - Статья
+ - прототип
+translation_of: Learn/JavaScript/Objects/Object_prototypes
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects")}}</div>
+
+<div>Прототипы - это механизм, с помощью которого объекты JavaScript наследуют свойства друг от друга. В этой статье мы объясним, как работают цепочки прототипов, и рассмотрим, как свойство prototype можно использовать для добавления методов к существующим конструкторам.</div>
+
+<div></div>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Необходимые знания:</th>
+ <td>
+ <p>Базовая компьютерная грамотность, базовое понимание HTML и CSS, знакомство с основами JavaScript (см. <a href="/ru/docs/Learn/JavaScript/%D0%9F%D0%B5%D1%80%D0%B2%D1%8B%D0%B5_%D1%88%D0%B0%D0%B3%D0%B8">Первые шаги</a> и <a href="ru/docs/Learn/JavaScript/Building_blocks">Строительные блоки</a>) и основы OOJS (см. <a href="/ru/docs/Learn/JavaScript/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B">Введение в объекты</a>).</p>
+ </td>
+ </tr>
+ <tr>
+ <th scope="row">Цель:</th>
+ <td>
+ <p>Понять прототипы объектов JavaScript, как работают прототипные цепочки и как добавить новые методы в <code>prototype</code> свойство.</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Язык_основанный_на_прототипах">Язык основанный на прототипах?</h2>
+
+<p>JavaScript часто описывают как язык <strong>прототипного наследования</strong> — каждый объект, имеет <strong>объект-прототип</strong>, который выступает как шаблон, от которого объект наследует методы и свойства. Объект-прототип так же может иметь свой прототип и наследовать его свойства и методы и так далее. Это часто называется <strong>цепочкой прототипов </strong>и объясняет почему одним объектам доступны свойства и методы которые определены в других объектах.</p>
+
+<p>Точнее, свойства и методы определяются в свойстве <code>prototype</code> функции-конструктора объектов, а не в самих объектах.</p>
+
+<p>В JavaScript создается связь между экземпляром объекта и его прототипом (свойство <code>__proto__</code>, которое является производным от свойства <code>prototype</code> конструктора), а свойства и методы обнаруживаются при переходе по цепочке прототипов.</p>
+
+<div class="note">
+<p><strong>Примечание</strong>: Важно понимать, что существует различие между прототипом объекта (который доступен через <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf">Object.getPrototypeOf(obj)</a></code> или через устаревшее свойство <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto">__proto__</a></code>) и свойством <code>prototype</code> в функциях-конструкторах. Первое свойство является свойством каждого экземпляра, а второе - свойством конструктора. То есть <code>Object.getPrototypeOf(new Foobar())</code> относится к тому же объекту, что и <code>Foobar.prototype</code>.</p>
+</div>
+
+<p>Давайте посмотрим на пример, чтобы стало понятнее.</p>
+
+<h2 id="Понимание_прототипа_объектов">Понимание прототипа объектов</h2>
+
+<p>Вернемся к примеру, когда мы закончили писать наш конструктор <code>Person()</code>- загрузите пример в свой браузер. Если у вас еще нет работы от последней статьи, используйте наш пример <a href="http://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-class-further-exercises.html">oojs-class-further-exercises.html</a> (см. Также <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-class-further-exercises.html">исходный код</a>).</p>
+
+<p>В этом примере мы определили конструкторную функцию, например:</p>
+
+<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">function</span> <span class="function token">Person</span><span class="punctuation token">(</span>first<span class="punctuation token">,</span> last<span class="punctuation token">,</span> age<span class="punctuation token">,</span> gender<span class="punctuation token">,</span> interests<span class="punctuation token">)</span> <span class="punctuation token">{</span>
+
+ <span class="comment token">// Определения методов и свойств</span>
+ </code><code> this.name = {
+ 'first': first,
+ 'last' : last
+ };
+ this.age = age;
+ this.gender = gender;
+ //...см. </code><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B">Введение в объекты</a> для полного определения<code class="language-js">
+<span class="punctuation token">}</span></code></pre>
+
+<p>Затем мы создаём экземпляр объекта следующим образом:</p>
+
+<pre class="brush: js">var person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']);</pre>
+
+<p>Если вы наберете «<code>person1.</code>» в вашей консоли JavaScript, вы должны увидеть, что браузер пытается автоматически заполнить это с именами участников, доступных на этом объекте:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13853/object-available-members.png" style="display: block; margin: 0 auto;"></p>
+
+<p>В этом списке вы увидите элементы, определенные в конструкторе person 1 — Person() — <code>name</code>, <code>age</code>, <code>gender</code>, <code>interests</code>, <code>bio</code>, и <code>greeting</code>. Однако вы также увидите некоторые другие элементы — <code>watch</code>, <code>valueOf</code>и т. д. — они определены в объекте прототипа Person (), который является <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object">Object</a></code>.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13891/MDN-Graphics-person-person-object-2.png" style="display: block; height: 150px; margin: 0px auto; width: 700px;"></p>
+
+<p>Итак, что произойдет, если вы вызываете метод в <code>person1</code>, который фактически определен в <code>Object</code>? Например:</p>
+
+<pre class="brush: js">person1.valueOf()</pre>
+
+<p>Этот метод — <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf">Object.valueOf()</a></code>наследуется <code>person1</code>, потому что его конструктором является <code>Person()</code>, а прототипом <code>Person()</code> является <code>Object()</code>. <code>valueOf()</code> возвращает значение вызываемого объекта — попробуйте и убедитесь! В этом случае происходит следующее:</p>
+
+<ul>
+ <li>Сначала браузер проверяет, имеет ли объект <code>person1</code> доступный в нем метод <code>valueOf()</code>, как определено в его конструкторе <code>Person()</code>.</li>
+ <li>Это не так, поэтому следующим шагом браузер проверяет, имеет ли прототип объекта (<code>Object()</code>) конструктора <code>Person()</code> доступный в нем метод  <code>valueOf()</code>. Так оно и есть, поэтому он вызывается, и все хорошо!</li>
+</ul>
+
+<div class="note">
+<p><strong>Примечание:</strong> Мы хотим повторить, что методы и свойства <strong>не</strong> копируются из одного объекта в другой в цепочке прототипов - к ним обращаются, поднимаясь по цепочке, как описано выше.</p>
+</div>
+
+<div class="note">
+<p><strong>Примечание</strong>: Официально нет способа получить доступ к объекту прототипа объекта напрямую - «ссылки» между элементами в цепочке определены во внутреннем свойстве, называемом <code>[[prototype]]</code> в спецификации для языка JavaScript ( см. {{glossary("ECMAScript")}}). Однако у большинства современных браузеров есть свойство, доступное для них под названием <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto">__proto__</a></code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto"> </a>(это 2 подчеркивания с обеих сторон), который содержит объект-прототип объекта-конструктора. Например, попробуйте <code>person1.__proto__</code> и <code>person1.__proto__.__proto__</code>, чтобы увидеть, как выглядит цепочка в коде!</p>
+
+<p>С ECMAScript 2015 вы можете косвенно обращаться к объекту прототипа объекта <code>Object.getPrototypeOf (obj)</code>.</p>
+</div>
+
+<h2 id="Свойство_prototype_Где_определены_унаследованные_экземпляры">Свойство prototype: Где определены унаследованные экземпляры</h2>
+
+<p>Итак, где определены наследуемые свойства и методы? Если вы посмотрите на страницу со ссылкой <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object">Object</a></code>, вы увидите в левой части большое количество свойств и методов - это намного больше, чем количество унаследованных членов, доступных для объекта <code>person1</code>. Некоторые из них унаследованы, а некоторые нет - почему это?</p>
+
+<p>Как упоминалось выше, наследованные свойства это те, что определены в свойстве <code>prototype</code> (вы можете называть это подпространством имен), то есть те, которые начинаются с <code>Object.prototype.</code>, а не те, которые начинаются с простого <code>Object</code>. Значение свойства <code>prototype</code> - это объект, который в основном представляет собой контейнер для хранения свойств и методов, которые мы хотим наследовать объектами, расположенными дальше по цепочке прототипов.</p>
+
+<p>Таким образом <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/watch">Object.prototype.watch()</a></code>, <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf">Object.prototype.valueOf()</a></code> и т. д. доступны для любых типов объектов, которые наследуются от <code>Object.prototype</code>, включая новые экземпляры объектов, созданные из конструктора <code>Person()</code> .</p>
+
+<p><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is">Object.is()</a></code>, <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys">Object.keys()</a></code> и другие члены, не определенные в контейнере <code>prototype</code>, не наследуются экземплярами объектов или типами объектов, которые наследуются от <code>Object.prototype</code>. Это методы / свойства, доступные только в конструкторе <code>Object()</code>.</p>
+
+<div class="note">
+<p><strong>Примечание</strong>: Это кажется странным - как у вас есть метод, определенный для конструктора, который сам по себе является функцией? Ну, функция также является типом объекта - см. Ссылку на конструктор <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function">Function()</a></code>, если вы нам не верите.</p>
+</div>
+
+<ol>
+ <li>Вы можете проверить существующие свойства прототипа для себя - вернитесь к нашему предыдущему примеру и попробуйте ввести следующее в консоль JavaScript:
+ <pre class="brush: js">Person.prototype</pre>
+ </li>
+ <li>Результат покажет вам не много, ведь мы ничего не определили в прототипе нашего конструктора! По умолчанию <code>prototype</code> конструктора всегда пуст. Теперь попробуйте следующее:
+ <pre class="brush: js">Object.prototype</pre>
+ </li>
+</ol>
+
+<p>Вы увидите большое количество методов, определенных для свойства <code>prototype</code> <code>Object</code>'а , которые затем доступны для объектов, которые наследуются от <code>Object</code>, как показано выше.</p>
+
+<p>Вы увидите другие примеры наследования цепочек прототипов по всему JavaScript - попробуйте найти методы и свойства, определенные на прототипе глобальных объектов <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code>, <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date">Date</a></code>, <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number">Number</a></code> и <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">Array</a></code>, например. Все они имеют несколько элементов, определенных на их прототипе, поэтому, например, когда вы создаете строку, вот так:</p>
+
+<pre class="brush: js">var myString = 'This is my string.';</pre>
+
+<p>В <code>myString</code> сразу есть множество полезных методов, таких как <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split">split()</a></code>, <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf">indexOf()</a></code>, <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace">replace()</a></code> и т. д.</p>
+
+<div class="warning">
+<p><strong>Важно</strong>: Свойство <code>prototype</code> является одной из наиболее противоречивых названий частей JavaScript - вы можете подумать, что <code>this</code> указывает на объект прототипа текущего объекта, но это не так (это внутренний объект, к которому можно получить доступ <code>__proto__</code>, помните ?). <code>prototype</code> вместо этого - свойство, содержащее объект, на котором вы определяете членов, которые вы хотите наследовать.</p>
+</div>
+
+<h2 id="Снова_create">Снова create()</h2>
+
+<p>Ранее мы показали, как метод <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create">Object.create()</a></code> может использоваться для создания нового экземпляра объекта.</p>
+
+<ol>
+ <li>Например, попробуйте это в консоли JavaScript предыдущего примера:
+ <pre class="brush: js">var person2 = Object.create(person1);</pre>
+ </li>
+ <li>На самом деле <code>create()</code>создает новый объект из указанного объекта-прототипа. Здесь <code>person2</code> создается с помощью <code>person1</code> в качестве объекта-прототипа. Это можно проверить, введя в консоли следующее:
+ <pre class="brush: js">person2.__proto__</pre>
+ </li>
+</ol>
+
+<p>Это вернет объект <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">person1</span></font>.</p>
+
+<h2 id="Свойство_constructor">Свойство constructor</h2>
+
+<p>Каждая функция-конструктор имеет свойство <code>prototype</code>, значением которого является объект, содержащий свойство <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor">constructor</a></code>. Это свойство <code>constructor</code> указывает на исходную функцию-конструктор. Как вы увидите в следующем разделе, свойства, определенные в свойстве <code>Person.prototype</code> (или в общем случае в качестве свойства прототипа функции конструктора, который является объектом, как указано в предыдущем разделе) становятся доступными для всех объектов экземпляра, созданных с помощью конструктор <code>Person()</code>. Следовательно, свойство конструктора также доступно для объектов <code>person1</code> и <code>person2</code>.</p>
+
+<ol>
+ <li>Например, попробуйте эти команды в консоли:
+ <pre class="brush: js">person1.constructor
+person2.constructor</pre>
+
+ <p>Они должны возвращать конструктор <code>Person()</code>, поскольку он содержит исходное определение этих экземпляров.</p>
+
+ <p>Хитрый трюк заключается в том, что вы можете поместить круглые скобки в конец свойства <code>constructor</code> (содержащие любые требуемые параметры) для создания другого экземпляра объекта из этого конструктора. Конструктор - это функция в конце концов, поэтому ее можно вызвать с помощью круглых скобок; вам просто нужно включить ключевое слово <code>new</code>, чтобы указать, что вы хотите использовать эту функцию в качестве конструктора.</p>
+ </li>
+ <li>Попробуйте это в консоли:
+ <pre class="brush: js">var person3 = new person1.constructor('Karen', 'Stephenson', 26, 'female', ['playing drums', 'mountain climbing']);</pre>
+ </li>
+ <li>Теперь попробуйте получить доступ к функциям вашего нового объекта, например:
+ <pre class="brush: js">person3.name.first
+person3.age
+person3.bio()</pre>
+ </li>
+</ol>
+
+<p>Это хорошо работает. Вам не нужно будет использовать его часто, но это может быть действительно полезно, если вы хотите создать новый экземпляр и не имеете ссылки на исходный конструктор, который легко доступен по какой-либо причине.</p>
+
+<p>Свойство <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor">constructor</a></code> имеет другие применения. Например, если у вас есть экземпляр объекта и вы хотите вернуть имя конструктора этого экземпляра, вы можете использовать следующее:</p>
+
+<pre class="brush: js">instanceName.constructor.name</pre>
+
+<p>Например, попробуйте это:</p>
+
+<pre class="brush: js">person1.constructor.name
+</pre>
+
+<div class="note">
+<p><strong>Примечание</strong>: Значение <code>constructor.name</code> может измениться (из-за прототипического наследования, привязки, препроцессоров, транспилеров и т. д.), Поэтому для более сложных примеров вы захотите использовать оператор <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof">instanceof</a></code>.</p>
+</div>
+
+<ol>
+</ol>
+
+<h2 id="Изменение_прототипов">Изменение прототипов</h2>
+
+<p>Давайте рассмотрим пример изменения свойства <code>prototype</code> функции-конструктора — методы, добавленные в прототип, затем доступны для всех экземпляров объектов, созданных из конструктора.</p>
+
+<ol>
+ <li>Вернитесь к нашему примеру <a href="http://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-class-further-exercises.html">oojs-class-further-exercises.html</a> и создайте локальную копию <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-class-further-exercises.html">исходного кода</a>. Ниже существующего JavaScript добавьте следующий код, который добавляет новый метод в свойство <code>prototype</code> конструктора:
+
+ <pre class="brush: js">Person.prototype.farewell = function() {
+ alert(this.name.first + ' has left the building. Bye for now!');
+};</pre>
+ </li>
+ <li>Сохраните код и загрузите страницу в браузере и попробуйте ввести следующее в текстовый ввод:
+ <pre class="brush: js">person1.farewell();</pre>
+ </li>
+</ol>
+
+<p>Должно появиться всплывающее окно, с именем пользователя, определенным в конструкторе. Это действительно полезно, но ещё более полезно то, что вся цепочка наследования обновляется динамически, автоматически делая этот новый метод доступным для всех экземпляров объектов, полученных из конструктора.</p>
+
+<p>Подумайте об этом на мгновение. В нашем коде мы определяем конструктор, затем мы создаем экземпляр объекта из конструктора, <em>затем</em> добавляем новый метод к прототипу конструктора:</p>
+
+<pre class="brush: js">function Person(first, last, age, gender, interests) {
+
+ // определения свойств и методов
+
+}
+
+var person1 = new Person('Tammi', 'Smith', 32, 'neutral', ['music', 'skiing', 'kickboxing']);
+
+Person.prototype.farewell = function() {
+ alert(this.name.first + ' has left the building. Bye for now!');
+};</pre>
+
+<p>Но метод <code>farewell()</code> <em>по-прежнему</em> доступен в экземпляре объекта <code>person1</code> - его элементы были автоматически обновлены, чтобы включить недавно определенный метод <code>farewell()</code>.</p>
+
+<div class="note">
+<p><strong>Примечание:</strong> Если у вас возникли проблемы с получением этого примера для работы, посмотрите на наш пример <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/oojs-class-prototype.html">oojs-class-prototype.html</a> (см. также это <a href="http://mdn.github.io/learning-area/javascript/oojs/advanced/oojs-class-prototype.html">running live</a>).</p>
+</div>
+
+<p>Вы редко увидите свойства, определенные в свойстве <code>prototype</code>, потому что они не очень гибки при таком определении. Например, вы можете добавить свойство следующим образом:</p>
+
+<pre class="brush: js">Person.prototype.fullName = 'Bob Smith';</pre>
+
+<p>Это не очень гибко, так как человека нельзя назвать так. Было бы намного лучше сделать это, создав <code>fullName</code> из <code>name.first</code> и <code>name.last</code>:</p>
+
+<pre class="brush: js">Person.prototype.fullName = this.name.first + ' ' + this.name.last;</pre>
+
+<p>Однако это не работает, поскольку в этом случае <code>this</code> будет ссылаться на глобальную область, а не на область функции. Вызов этого свойства вернет <code>undefined undefined</code>. Это отлично работало с методом, который мы определили ранее в прототипе, потому что он находится внутри области функций, которая будет успешно перенесена в область экземпляра объекта. Таким образом, вы можете определить постоянные свойства прототипа (т. е. те, которые никогда не нуждаются в изменении), но обычно лучше определять свойства внутри конструктора.</p>
+
+<p>Фактически, довольно распространенный шаблон для большего количества определений объектов - это определение свойств внутри конструктора и методов в прототипе. Это упрощает чтение кода, поскольку конструктор содержит только определения свойств, а методы разделены на отдельные блоки. Например:</p>
+
+<pre class="brush: js">// Определение конструктора и его свойств
+
+function Test(a, b, c, d) {
+ // определение свойств...
+}
+
+// Определение первого метода
+
+Test.prototype.x = function() { ... };
+
+// Определение второго метода
+
+Test.prototype.y = function() { ... };
+
+//...и так далее</pre>
+
+<p>Этот образец можно увидеть в действии в примере <a href="https://github.com/zalun/school-plan-app/blob/master/stage9/js/index.js">приложения плана школы </a>Петра Залевы.</p>
+
+<h2 id="Резюме">Резюме</h2>
+
+<p>В этой статье рассмотрены прототипы объектов JavaScript (в том числе и то, как прототип цепочки объектов позволяет объектам наследовать функции друг от друга), свойство прототипа и как его можно использовать для добавления методов к конструкторам и другие связанные с этой статьёй темы.</p>
+
+<p>В следующей статье мы рассмотрим то, как вы можете реализовать наследование функциональности между двумя собственными настраиваемыми объектами.</p>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects")}}</p>
+
+
+
+<h2 id="В_этом_модуле">В этом модуле</h2>
+
+<ul>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/Объекты/Основы">Основы объекта</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/Объекты/Object-oriented_JS">Объектно-ориентированный JavaScript для начинающих</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/Объекты/Object_prototypes">Прототипы объектов</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/Объекты/Inheritance">Наследование в JavaScript</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/Объекты/JSON">Работа с данными JSON</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/Объекты/Object_building_practice">Практика построения объектов</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/Объекты/Adding_bouncing_balls_features">Добавление функций в нашу демонстрацию прыгающих шаров</a></li>
+</ul>
diff --git a/files/ru/learn/javascript/объекты/основы/index.html b/files/ru/learn/javascript/объекты/основы/index.html
new file mode 100644
index 0000000000..a4e7cc0071
--- /dev/null
+++ b/files/ru/learn/javascript/объекты/основы/index.html
@@ -0,0 +1,257 @@
+---
+title: Основы объектов в JavaScript
+slug: Learn/JavaScript/Объекты/Основы
+tags:
+ - JavaScript
+ - ООП
+translation_of: Learn/JavaScript/Objects/Basics
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{NextMenu("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects")}}</div>
+
+<p class="summary">В этой статье мы рассмотрим объекты в JavaScript. Мы будем разбирать основы синтаксиса объектов JavaScript и заново изучим некоторый функционал JavaScript, который мы уже исследовали ранее на курсе, подтвердив тот факт, что большая часть функционала, с которым мы уже столкнулись, в действительности является объектами.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Необходимые знания:</th>
+ <td>Элементарная компьютерная грамотность, базовое понимание HTML и CSS, знакомство с основами JavaScript (см. <a href="/ru/docs/Learn/JavaScript/Первые_шаги">Первые шаги</a> и <a href="/ru/docs/Learn/JavaScript/Building_blocks">Структурные элементы</a>).</td>
+ </tr>
+ <tr>
+ <th scope="row">Цель:</th>
+ <td>Понимать основу теории перед началом объектно-ориентированного программирования, как это связано с JavaScript ("большинство сущностей являются объектами"), и как начать работу с объектами JavaScript.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Основы_объектов">Основы объектов</h2>
+
+<p>Объект — это совокупность связанных данных и/или функциональных возможностей. Обычно состоят из нескольких переменных и функций, которые называются свойства и методы, если они находятся внутри объектов. Разберём пример, чтобы показать, как они выглядят.</p>
+
+<p>Чтобы начать, скопируйте себе <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs.html">oojs.html</a> файл. В нём содержится очень мало: {{HTMLElement("script")}} элемент для написания в нём исходного кода. Мы будем использовать это как основу для изучения основ синтаксиса объектов. Во время работы с этим примером у вас должна быть открытая <a href="/ru/docs/Learn/Discover_browser_developer_tools#%D0%9A%D0%BE%D0%BD%D1%81%D0%BE%D0%BB%D1%8C_JavaScript">консоль JavaScript инструментов разработчика</a>, готовая к вводу некоторых команд.</p>
+
+<p>Как и во многих случаях в JavaScript, создание объекта часто начинается с определения и инициализации переменной. Попробуйте ввести следующий код JavaScript в ваш файл, а затем сохраните файл и обновите страницу браузера:</p>
+
+<pre class="brush: js notranslate">const person = {};</pre>
+
+<p>Если Вы введёте <code>person</code> в текстовое JS консоль и нажмёте клавишу Enter, должен получиться следующий результат:</p>
+
+<pre class="brush: js notranslate"><code class="language-js">Object</code><code> </code>{ }</pre>
+
+<p>Поздравляем, Вы только что создали Ваш первый объект. Но это пустой объект, поэтому мы не можем с ним ничего сделать. Давайте обновим наш объект, чтобы он выглядел так:</p>
+
+<pre class="brush: js notranslate">const person = {
+ name: ['Bob', 'Smith'],
+ age: 32,
+ gender: 'male',
+ interests: ['music', 'skiing'],
+ bio: function() {
+ alert(this.name[0] + ' ' + this.name[1] + ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.');
+ },
+ greeting: function() {
+ alert('Hi! I\'m ' + this.name[0] + '.');
+ }
+};
+</pre>
+
+<p>После сохранения и обновления, попробуйте ввести что-нибудь следующее в консоль JavaScript браузера:</p>
+
+<pre class="brush: js notranslate"><code class="language-js">person<span class="punctuation token">.</span>name</code>
+person.name[0]
+person.age
+person.interests[1]
+person.bio()
+person.greeting()</pre>
+
+<p>Теперь внутри объекта есть некоторые данные и функционал, и теперь можно получить доступ к ним с помощью некоторого лёгкого и простого синтаксиса!</p>
+
+<div class="note">
+<p><strong>Примечание</strong>: Если у вас возникли проблемы с применением файла в работе, попробуйте сравнить ваш код с нашей версией — см. <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-finished.html">oojs-finished.html</a> (также <a href="http://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-finished.html">see it running live</a>). Одна из распространенных ошибок, когда Вы начинаете с объектами ставить запятую в конце последнего члена — это приводит к ошибке.</p>
+</div>
+
+<p>Итак что здесь происходит? Объект состоит из нескольких элементов, каждый из которых имеет своё название (пример <code>name</code> и <code>age</code> выше), и значение (пример <code>['Bob', 'Smith']</code> и <code>32</code>). Каждая пара название/значение должны быть разделены запятой, а название и значение в каждом случае разделяются двоеточием. Синтаксис всегда следует этому образцу:</p>
+
+<pre class="brush: js notranslate">const objectName = {
+ member1Name: member1Value,
+ member2Name: member2Value,
+ member3Name: member3Value
+};</pre>
+
+<p>Значение члена объекта может быть чем угодно — в нашем объекте person есть строка, число, два массива, и две функции. Первые четыре элемента это элементы данных, относящиеся к <strong>свойствам</strong> объекта. Последние два элемента являются функциями, которые позволяют объекту что-то сделать с элементами данных, и называются <strong>методами</strong> объекта.</p>
+
+<p>Такие объекты называются <strong>литералами объекта</strong> (<strong>object literal</strong>) — мы буквально вписали все содержимое объекта для его создания. Этот способ сильно отличается от объектов реализованных классами, которые мы рассмотрим позже.</p>
+
+<p>Очень часто для создания объекта используется литерал объекта когда вам нужно каким-то образом перенести ряд структурированных, связанных элементов данных, например, отправляя запрос на сервер, для размещения их в базе данных. Отправка одного объекта намного эффективнее, чем отправка нескольких элементов по отдельности, и с ним легче работать чем с массивом, если требуется идентифицировать отдельные элементы по имени. </p>
+
+<h2 id="Точечная_запись_Dot_notation">Точечная запись (Dot notation)</h2>
+
+<p>Выше Вы получили доступ к свойствам и методам используя <strong>точечную запись (dot notation). </strong>Имя объекта (person) действует как <strong>пространство имен (namespace) </strong>— оно должно быть введено первым, для того чтобы получить доступ ко всему что заключено (<strong>encapsulated)</strong> внутри объекта. Далее Вы пишете точку, затем элемент, к которому хотите получить доступ — это может быть имя простого свойства, элемент массива, или вызов одного из методов объекта, например:</p>
+
+<pre class="brush: js notranslate">person.age
+person.interests[1]
+person.bio()</pre>
+
+<h3 id="Внутренние_пространства_имен_Sub-namespaces">Внутренние пространства имен (Sub-namespaces)</h3>
+
+<p>Можно даже сделать значением элемента объекта другой объект. Например, попробуйте изменить значение свойства name с такого</p>
+
+<pre class="brush: js notranslate">name: ['Bob', 'Smith'],</pre>
+
+<p>на такое</p>
+
+<pre class="brush: js notranslate">name : {
+ first: 'Bob',
+ last: 'Smith'
+},</pre>
+
+<p>Здесь мы фактически создаем <strong>внутреннее пространство имен (sub-namespace). </strong>Это звучит сложно, но на самом деле это не так — для доступа к этим элементам Вам нужно сделать один дополнительный шаг с еще одной точкой. Попробуйте в консоли браузера следующее: </p>
+
+<pre class="brush: js notranslate">person.name.first
+person.name.last</pre>
+
+<p><strong>Важно</strong>: На этом этапе вам также нужно будет пересмотреть код метода и изменить все экземпляры с</p>
+
+<pre class="brush: js notranslate">name[0]
+name[1]</pre>
+
+<p>на</p>
+
+<pre class="brush: js notranslate">name.first
+name.last</pre>
+
+<p>Иначе ваши методы больше не будут работать.</p>
+
+<h2 id="Скобочная_запись_Bracket_notation">Скобочная запись (Bracket notation)</h2>
+
+<p>Существует другой способ получить свойства объекта — использовать скобочную запись (bracket notation). Вместо написания этого кода:</p>
+
+<pre class="brush: js notranslate">person.age
+person.name.first</pre>
+
+<p>Вы можете использовать следующий</p>
+
+<pre class="brush: js notranslate">person['age']
+person['name']['first']</pre>
+
+<p>Это выглядит очень похоже на то, как Вы получаете элементы массива, и в принципе это так и есть — вместо использования числовых индексов для выбора элемента, Вы ассоциируете имя свойства для каждого значения. Ничего удивительного, что эти объекты иногда называют ассоциативными массивами — они сопоставляют строки со значениями так же, как массивы сопоставляют числовые индексы со значениями.</p>
+
+<h2 id="Запись_элементов_в_объект">Запись элементов в объект</h2>
+
+<p>До сих пор мы рассмастривали только возврат (или получение) элементов объекта — Вы так же можете установить (обновить) значение элемента объекта просто объявив элемент, который Вы хотите установить (используя точечную или скобочную запись), например:</p>
+
+<pre class="brush: js notranslate">person.age = 45;
+person['name']['last'] = 'Cratchit';</pre>
+
+<p>Попробуйте ввести эти строки, а затем снова верните элементы, чтобы увидеть, как они изменились</p>
+
+<pre class="brush: js notranslate">person.age
+person['name']['last']</pre>
+
+<p>Вы можете не просто обновлять и устанавливать значения свойств и методов объекта, а так же устанавливать совершенно новые элементы. Попробуйте их в консоли JS:</p>
+
+<pre class="brush: js notranslate">person['eyes'] = 'hazel';
+person.farewell = function() { alert("Bye everybody!"); }</pre>
+
+<p>Теперь Вы можете проверить ваши новые элементы:</p>
+
+<pre class="brush: js notranslate">person['eyes']
+person.farewell()</pre>
+
+<p>Одним из полезных аспектов скобочной записи является то, что с ее помощью можно динамически задавать не только значения элементов, но и их имена. Предположим, что мы хотим, чтобы пользователи могли хранить пользовательские типы данных, введя имя и значение элемента в два следующих поля? Мы могли бы получить эти значения следующим образом:</p>
+
+<pre class="brush: js notranslate">let myDataName = nameInput.value;
+let myDataValue = nameValue.value;</pre>
+
+<p>Затем мы можем добавить имя и значение этого нового элемента в объект <code>person</code> таким образом:</p>
+
+<pre class="brush: js notranslate">person[myDataName] = myDataValue;</pre>
+
+<p>Чтобы проверить это, попробуйте добавить следующие строки в свой код, после закрывающей скобки объекта <code>person</code> :</p>
+
+<pre class="brush: js notranslate">let myDataName = 'height';
+let myDataValue = '1.75m';
+person[myDataName] = myDataValue;</pre>
+
+<p>Теперь попробуйте сохранить и обновить, затем введите следующее в консоль браузера:</p>
+
+<pre class="brush: js notranslate">person.height</pre>
+
+<p>Добавление свойства объекта с использованием вышеописанного метода невозможно с использованием точечной записи, которая может принимать только литеральное имя элемента, а не значение переменной указывающее на имя.</p>
+
+<h2 id="Что_такое_this">Что такое "this"?</h2>
+
+<p>Возможно, вы заметили что-то странное в наших методах. Посмотрите на этот пример:</p>
+
+<pre class="brush: js notranslate">greeting: function() {
+ alert('Hi! I\'m ' + this.name.first + '.');
+}</pre>
+
+<p>Вы, вероятно, задаетесь вопросом, что такое "this"? Ключевое слово <code>this</code>, ссылается на текущий объект, внутри которого пишется код — поэтому в нашем случае <code>this</code> равен объекту <code>person</code>. Но почему просто не написать <code>person</code>? Как Вы увидите в статье <a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS">Object-oriented JavaScript for beginners</a> (Объектно-ориентированный JavaScript для начинающих), когда мы начинаем создавать конструкторы и т.д., <code>this</code> очень полезен — он всегда будет гарантировать, что используется верное значение, когда контекст элемента изменяется (например, два разных экземпляра объекта <code>person</code> могут иметь разные имена, но захотят использовать свое собственное имя при приветствии.</p>
+
+<p>Давайте проиллюстритуем, что мы имеем в виду, с упрощенной парой объектов <code>person</code> :</p>
+
+<pre class="brush: js notranslate">const person1 = {
+ name: 'Chris',
+ greeting: function() {
+ alert('Hi! I\'m ' + this.name + '.');
+ }
+}
+
+const person2 = {
+ name: 'Brian',
+ greeting: function() {
+ alert('Hi! I\'m ' + this.name + '.');
+ }
+}</pre>
+
+<p>В этом случае, <code>person1.greeting()</code> выведет "Hi! I'm Chris.". <code>person2.greeting()</code>, с другой стороны, выведет "Hi! I'm Brian.", хотя код метода одинаковый в обоих случаях. Как мы сказали ранее, <code>this</code> равен объекту, внутри которого находится код — это не очень полезно, когда Вы пишите литералы объектов вручную, но оно действительно помогает, когда Вы генерируете объекты динамически (например используя конструкторы). Это станет понятнее чуть позже.</p>
+
+<h2 id="Все_это_время_вы_использовали_объекты">Все это время вы использовали объекты</h2>
+
+<p>Пока Вы проходили эти примеры, Вы вероятно заметили, что точечная запись, которую Вы использовали, выглядит очень знакомо. Это потому, что Вы использовали ее на протяжении всего курса! Каждый раз, когда мы работаем над примером, использующим встроенный API браузера или объект JavaScript, мы использовали объекты, потому что такие функции построены с использованием тех же структур объектов, которые мы здесь рассматривали, хотя и более сложные, чем наши собственные пользовательские примеры. </p>
+
+<p>Поэтому, когда Вы использовали строковые методы, такие как:</p>
+
+<pre class="brush: js notranslate">myString.split(',');</pre>
+
+<p>Вы использовали метод доступный в экземпляре класса <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code>. Каждый раз создавая строку в вашем коде, эта строка автоматически создается как экземпляр <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code>, и поэтому имеет несколько общих методов/свойств, доступных на нем.</p>
+
+<p>Когда Вы обращались к объектной модели документа (DOM), используя следующие строки:</p>
+
+<pre class="brush: js notranslate">const myDiv = document.createElement('div');
+const myVideo = document.querySelector('video');</pre>
+
+<p>Вы использовали методы доступные в экземпляре класса <code><a href="/en-US/docs/Web/API/Document">Document</a></code>. Для каждой загруженной веб-страницы создается экземпляр <code><a href="/en-US/docs/Web/API/Document">Document</a></code>, называемый <code>document</code>, который представляет всю структуру страницы, ее содержимое и другие функции, такие как URL-адрес. Опять же, это означает, что он имеет несколько общих методов/свойств, доступных на нем.</p>
+
+<p>То же самое относится и к любому другому встроенному объекту/API, который вы использовали — <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">Array</a></code>, <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math">Math</a></code>, и т. д.</p>
+
+<p>Обратите внимание, что встроенные объекты/API не всегда создают экземпляры объектов автоматически. Как пример, <a href="/ru/docs/Web/API/Notifications_API">Notifications API</a> — который позволяет новым браузерам запускать системные уведомления, требует, чтобы Вы создавали новый экземпляр объекта с помощью конструктора для каждого уведомления, которое Вы хотите запустить. Попробуйте ввести следующее в консоль JavaScript:</p>
+
+<pre class="brush: js notranslate">const myNotification = new Notification('Hello!');</pre>
+
+<p>Опять же, мы рассмотрим конструкторы в следующей статье.</p>
+
+<div class="note">
+<p><strong>Примечание</strong>: Полезно подумать о том, как объекты взаимодействуют посредством передачи сообщений - когда объекту требуется другой объект для выполнения какого-либо действия, он часто отправляет сообщение другому объекту через один из его методов и ждет ответа, который мы знаем как возвращаемое (return) значение.</p>
+</div>
+
+<h2 id="Резюме">Резюме</h2>
+
+<p>Поздравляем, Вы достигли конца нашей первой статьи о объектах JS, теперь у вас должно быть хорошее представление о том, как работать с объектами в JavaScript - в том числе создавать свои собственные простые объекты. Вы также должны понимать, что объекты очень полезны в качестве структур для хранения связанных данных и функциональности - если бы мы пытались отслеживать все свойства и методы в нашем объекте <code>person</code> как отдельные переменные и функции, это было неэффективно, и мы бы рисковали столкнуться с другими переменными и функциями с такими же именами. Объекты позволяют нам безопасно хранить информацию в своем собственном блоке, вне опасности.</p>
+
+<p>В следующей статье мы начнем рассматривать теорию объектно-ориентированного программирования (OOП) и как эти техники могут быть использованны в JavaScript </p>
+
+<p>{{NextMenu("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects")}}</p>
+
+<h2 id="В_этом_модуле">В этом модуле</h2>
+
+<ul>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B/%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D1%8B">Основы объекта</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B/Object-oriented_JS">Объектно-ориентированный JavaScript для начинающих</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B/Object_prototypes">Прототипы объектов</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B/Inheritance">Наследование в JavaScript</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B/JSON">Работа с данными JSON</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B/Object_building_practice">Практика построения объектов</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D1%8B/Adding_bouncing_balls_features">Добавление функций в нашу демонстрацию прыгающих шаров</a></li>
+</ul>
diff --git a/files/ru/learn/javascript/первые_шаги/a_first_splash/index.html b/files/ru/learn/javascript/первые_шаги/a_first_splash/index.html
new file mode 100644
index 0000000000..b2a811b992
--- /dev/null
+++ b/files/ru/learn/javascript/первые_шаги/a_first_splash/index.html
@@ -0,0 +1,675 @@
+---
+title: Первое погружение в JavaScript
+slug: Learn/JavaScript/Первые_шаги/A_first_splash
+translation_of: Learn/JavaScript/First_steps/A_first_splash
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/What_is_JavaScript", "Learn/JavaScript/Первые_шаги/Что_пошло_не_так", "Learn/JavaScript/Первые_шаги")}}</div>
+
+<p class="summary">Теперь, когда вы получили <a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/First_steps/What_is_JavaScript">базовое представление о JavaScript</a> — самое время познакомиться с ним на практике! В данной статье представлен ускоренный практический курс, демонстрирующий основные возможности JavaScript. В этом курсе, шаг за шагом, вы создадите простую игру «Угадай число».</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Необходимые навыки:</th>
+ <td>Базовая компьютерная грамотность, знание основ HTML и CSS, понимание что такое и для чего нужен JavaScript.</td>
+ </tr>
+ <tr>
+ <th scope="row">Цели:</th>
+ <td>Получение первого опыта в программировании на JavaScript.</td>
+ </tr>
+ </tbody>
+</table>
+
+<p>Вам не придется сразу понимать весь код — мы только хотим познакомить вас с базовыми концепциями языка и дать представление о том, как работает JavaScript (и другие языки программирования). В дальнейших статьях вы изучите эти концепции более подробно!</p>
+
+<div class="note">
+<p>Большинство языковых конструкций JavaScript, с которыми вы познакомитесь (функции, циклы и т.д.), имеют аналоги в других языках программирования — т.е. языки имеют разный синтаксис, но концепции в большинстве случаев те же самые.</p>
+</div>
+
+<h2 id="Думай_как_программист">Думай как программист</h2>
+
+<p>Одним из самых трудных и значимых моментов в обучении программированию является не изучение непосредственно синтаксиса языка, а понимание того как применять его для решения реальных задач. Вам нужно начать думать как программист, обычно это означает следующее:</p>
+
+<ul>
+ <li>Сначала вы разрабатываете логику (структуру, алгоритм выполнения) программы — общие задачи, что и в каких случаях она должна делать, как должна завершиться и т.д., т.е. создаете описание полного цикла её работы.</li>
+ <li>Затем определяете какие конструкции (возможности) языка вам понадобятся и как заставить их работать вместе — для последовательного выполнения всех этапов разработанной логики.</li>
+</ul>
+
+<p>Всё вместе это потребует тяжелой работы, знания языка, практики в написании кода - и немного творчества. Чем больше вы будете заняты решением практических задач, тем быстрее будете расти в программировании. Мы не обещаем, что вы сразу начнете "думать как программист", но предоставим для этого достаточно возможностей в этой статье.</p>
+
+<p>Учитывая вышесказанное, на примере простой игры, давайте детально разберем каждый этап создания программы и познакомимся с некоторыми конструкциями языка.</p>
+
+<h2 id="Игра_«Угадай_число»">Игра «Угадай число»</h2>
+
+<p>В этой статье мы покажем вам как создать простую игру, которую вы видите ниже:</p>
+
+<div class="hidden">
+<h6 id="Top_hidden_code">Top hidden code</h6>
+
+<pre class="brush: html notranslate">&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+
+&lt;head&gt;
+ &lt;meta charset="utf-8"&gt;
+ &lt;title&gt;Number guessing game&lt;/title&gt;
+ &lt;style&gt;
+ html {
+ font-family: sans-serif;
+ }
+
+ body {
+ width: 50%;
+ max-width: 800px;
+ min-width: 480px;
+ margin: 0 auto;
+ }
+
+ .lastResult {
+ color: white;
+ padding: 3px;
+ }
+ &lt;/style&gt;
+&lt;/head&gt;
+
+&lt;body&gt;
+ &lt;h1&gt;Number guessing game&lt;/h1&gt;
+ &lt;p&gt;We have selected a random number between 1 and 100. See if you can guess it in 10 turns or less. We'll tell you if your guess was too high or too low.&lt;/p&gt;
+ &lt;div class="form"&gt; &lt;label for="guessField"&gt;Enter a guess: &lt;/label&gt;&lt;input type="text" id="guessField" class="guessField"&gt; &lt;input type="submit" value="Submit guess" class="guessSubmit"&gt; &lt;/div&gt;
+ &lt;div class="resultParas"&gt;
+ &lt;p class="guesses"&gt;&lt;/p&gt;
+ &lt;p class="lastResult"&gt;&lt;/p&gt;
+ &lt;p class="lowOrHi"&gt;&lt;/p&gt;
+ &lt;/div&gt;
+&lt;/body&gt;
+&lt;script&gt;
+ // Your JavaScript goes here
+ var randomNumber = Math.floor(Math.random() * 100) + 1;
+ var guesses = document.querySelector('.guesses');
+ var lastResult = document.querySelector('.lastResult');
+ var lowOrHi = document.querySelector('.lowOrHi');
+ var guessSubmit = document.querySelector('.guessSubmit');
+ var guessField = document.querySelector('.guessField');
+ var guessCount = 1;
+ var resetButton;
+
+ function checkGuess() {
+ var userGuess = Number(guessField.value);
+ if (guessCount === 1) {
+ guesses.textContent = 'Previous guesses: ';
+ }
+
+ guesses.textContent += userGuess + ' ';
+
+ if (userGuess === randomNumber) {
+ lastResult.textContent = 'Congratulations! You got it right!';
+ lastResult.style.backgroundColor = 'green';
+ lowOrHi.textContent = '';
+ setGameOver();
+ } else if (guessCount === 10) {
+ lastResult.textContent = '!!!GAME OVER!!!';
+ lowOrHi.textContent = '';
+ setGameOver();
+ } else {
+ lastResult.textContent = 'Wrong!';
+ lastResult.style.backgroundColor = 'red';
+ if(userGuess &lt; randomNumber) {
+ lowOrHi.textContent='Last guess was too low!' ;
+ } else if(userGuess &gt; randomNumber) {
+ lowOrHi.textContent = 'Last guess was too high!';
+ }
+ }
+
+ guessCount++;
+ guessField.value = '';
+ }
+
+ guessSubmit.addEventListener('click', checkGuess);
+
+ function setGameOver() {
+ guessField.disabled = true;
+ guessSubmit.disabled = true;
+ resetButton = document.createElement('button');
+ resetButton.textContent = 'Start new game';
+ document.body.appendChild(resetButton);
+ resetButton.addEventListener('click', resetGame);
+ }
+
+ function resetGame() {
+ guessCount = 1;
+ var resetParas = document.querySelectorAll('.resultParas p');
+ for(var i = 0 ; i &lt; resetParas.length ; i++) {
+ resetParas[i].textContent='';
+ }
+
+ resetButton.parentNode.removeChild(resetButton);
+ guessField.disabled = false;
+ guessSubmit.disabled = false;
+ guessField.value='';
+ guessField.focus();
+ lastResult.style.backgroundColor='white';
+ randomNumber=Math.floor(Math.random() * 100) + 1;
+ }
+&lt;/script&gt;
+
+&lt;/html&gt;</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Top_hidden_code', '100%', 320) }}</p>
+
+<p>Поиграйте в нее - познакомьтесь с игрой, прежде чем двигаться дальше.</p>
+
+<p>Давайте представим, что ваш босс дал вам следующую информацию для создания этой игры:</p>
+
+<blockquote>
+<p>Я хочу чтобы ты создал простую игру по принципу "Угадай число". Игра должна случайным образом генерировать число от 0 до 100, затем игрок должен отгадать это число за 10 попыток. После каждой попытки игроку сообщают угадал он число или не угадал и если он ошибся, то ему сообщается, что загаданное число больше или меньше того, которое он ввел. Так же необходимо показывать игроку числа из его предыдущих попыток. Игра будет окончена, если игрок угадал число верно или если у него кончатся все попытки. После окончания игры игроку будет дана возможность сыграть в игру еще раз.</p>
+</blockquote>
+
+<p>Поглядев на это краткое изложение, первое, что мы можем сделать - это начать разбивать его на простые действия, максимально думая как программист:</p>
+
+<ol>
+ <li>Сгенерировать случайное число между 1 и 100.</li>
+ <li>Начать запись количества попыток игрока угадать число. Начать с 1.</li>
+ <li>Предоставить попытку угадать игроку загаданное число.</li>
+ <li>Как только попытка угадать была отправлена, сначала записать ее где-нибудь, чтобы пользователь мог увидеть свои предыдущие попытки</li>
+ <li>Далее, проверить было ли это число верным.</li>
+ <li>Если число верное:
+ <ol>
+ <li>Показать поздравительное сообщение.</li>
+ <li>Оградить игрока от дальнейшей возможности ввода чисел (это испортит игру).</li>
+ <li>Предоставить возможность для перезапуска игры.</li>
+ </ol>
+ </li>
+ <li>Если число не верное и есть попытки:
+ <ol>
+ <li>Сказать игроку, что он не угадал.</li>
+ <li>Разрешить ему использовать еще попытку.</li>
+ <li>Повысить число попыток на 1.</li>
+ </ol>
+ </li>
+ <li>Если число не верное и попыток нет:
+ <ol>
+ <li>Сказать игроку, что игра окончена.</li>
+ <li>Оградить игрока от дальнейшей возможности ввода чисел (это испортит игру).</li>
+ <li>Предоставить возможность для перезапуска игры.</li>
+ </ol>
+ </li>
+ <li>Во время перезапуска игры убедиться, что игровая логика и пользовательский интерфейс полностью сбросились на начальные значения и далее перейти обратно к пункту 1.</li>
+</ol>
+
+<p>Давайте теперь перейдем к рассмотрению того, как мы можем превратить эти шаги в код, создавая примеры и исследуя возможности JavaScript по ходу.</p>
+
+<h3 id="Подготовка">Подготовка</h3>
+
+<p>В начале этого урока, мы хотели бы, чтобы вы создали локальную копию файла  <a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/first-splash/number-guessing-game-start.html">number-guessing-game-start.html</a>  (<a href="http://mdn.github.io/learning-area/javascript/introduction-to-js-1/first-splash/number-guessing-game-start.html">см. здесь</a>).  Откройте его как в текстовом редакторе, так и в веб-браузере. На данный момент вы увидите простой заголовок, абзац с инструкцией и форму для ввода предположения, но форма в настоящее время ничего не сделает.</p>
+
+<p>Место, где мы будем добавлять весь наш код, находится внутри элемента {{htmlelement("script")}} в нижней части HTML:</p>
+
+<pre class="brush: html notranslate">&lt;script&gt;
+
+ // Your JavaScript goes here
+
+&lt;/script&gt;
+</pre>
+
+<h3 id="Добавление_переменных_для_хранения_данных">Добавление переменных для хранения данных</h3>
+
+<p>Давайте начнем. Прежде всего добавьте следующие строки внутри элемента  {{htmlelement("script")}} :</p>
+
+<pre class="notranslate"><code>var randomNumber = Math.floor(Math.random() * 100) + 1;
+
+var guesses = document.querySelector('.guesses');
+var lastResult = document.querySelector('.lastResult');
+var lowOrHi = document.querySelector('.lowOrHi');
+
+var guessSubmit = document.querySelector('.guessSubmit');
+var guessField = document.querySelector('.guessField');
+
+var guessCount = 1;
+var resetButton;</code></pre>
+
+<p>В этом разделе кода устанавливаются переменные, необходимые для хранения данных, которые будет использоваться нашей программой. Переменные - это в основном контейнеры для значений (например, числа или строки текста). Вы создаете переменную с ключевым словом var, за которой следует имя для вашей переменной. Затем вы можете присвоить значение своей переменной знак равенства (=), за которым следует значение, которое вы хотите дать.</p>
+
+<p>В нашем примере:</p>
+
+<ul>
+ <li>Первой переменной - randomNumber - присваивается случайное число от 1 до 100, вычисленное с использованием математического алгоритма.</li>
+ <li>Следующие три переменные сделаны для хранения ссылок на абзацы результатов в нашем HTML и используются для вставки значений в абзацы, приведенные далее в коде:
+ <pre class="brush: html notranslate">&lt;p class="guesses"&gt;&lt;/p&gt;
+&lt;p class="lastResult"&gt;&lt;/p&gt;
+&lt;p class="lowOrHi"&gt;&lt;/p&gt;</pre>
+ </li>
+ <li>Следующие две переменных хранят ссылки на форму ввода текста и кнопку отправки а позже используются для управления подачи догадки .
+ <pre class="brush: html notranslate">&lt;label for="guessField"&gt;Enter a guess: &lt;/label&gt;&lt;input type="text" id="guessField" class="guessField"&gt;
+&lt;input type="submit" value="Submit guess" class="guessSubmit"&gt;</pre>
+ </li>
+ <li>Наши последние две переменные сохраняют количество догадок 1 (используется для отслеживания того, сколько догадок у игрока было), и ссылку на кнопку сброса, которая еще не существует (но позже).</li>
+</ul>
+
+<div class="note">
+<p><strong>Заметка</strong>:<strong> </strong>В дальнейшем вы узнаете намного больше о переменных, в следующей статье.</p>
+</div>
+
+<h3 id="Функции_Functions">Функции (Functions)</h3>
+
+<p>Затем добавьте следующие ниже предыдущего JavaScript:</p>
+
+<pre class="brush: js notranslate">function checkGuess() {
+ alert('I am a placeholder');
+}</pre>
+
+<p>Функции представляют собой многократно используемые блоки кода, написав один раз вы можете запускать их снова и снова, сохраняя нужный постоянно повторяющийся код. Это действительно полезно. Существует несколько способов определить функцию, но пока мы сосредоточимся на одном простом варианте. Здесь мы определили функцию используя ключевое слово <code>function</code>, за ним идет имя с двумя скобками после него. После этого мы добавляем две фигурные скобки (<code>{ }</code>). Внутри фигурных скобок содержится весь код, запускающийся всякий раз, когда вызываем функцию.</p>
+
+<p>Код запускается вводом имени функции, за которым следуют две скобки.</p>
+
+<p>Сейчас попробуйте сохранить код и обновить его в браузере.</p>
+
+<p>Перейдите к <a href="/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools">консоли JavaScript в инструментах разработчика</a>, и введите следующую строку:</p>
+
+<pre class="brush: js notranslate">checkGuess();</pre>
+
+<p>Вы должны увидеть предупреждение, в котором говорится "I am a placeholder"; в нашем коде мы определили функцию, которая создает предупреждение, когда ее вызывают.</p>
+
+<div class="note">
+<p><strong>Заметка</strong>: В дальнейшем вы намного больше узнаете о функциях.</p>
+</div>
+
+<h3 id="Операторы_Operators">Операторы (Operators)</h3>
+
+<p>Операторы JavaScript позволяют нам проводить проверки, математические рассчеты, объединять строки вместе и выполнять другие подобные действия.</p>
+
+<p>Сохраните наш код и обновите страницу показанную в браузере. Откройте <a href="/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools">консоль JavaScript</a>, если вы еще её не открыли, чтобы попробовать ввести текст из приведенных ниже примеров — введите каждую строчку из столбца "Пример", нажимая Enter после каждого из них, и посмотрите какие результаты они возвращают. Если у вас нет доступа к инструментам разработчика в браузере, вы всегда можете использовать простую встроенную консоль, показанную ниже:</p>
+
+<div class="hidden">
+<h6 id="Hidden_code">Hidden code</h6>
+
+<pre class="brush: html notranslate">&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+ &lt;head&gt;
+ &lt;meta charset="utf-8"&gt;
+ &lt;title&gt;JavaScript console&lt;/title&gt;
+ &lt;style&gt;
+ * {
+ box-sizing: border-box;
+ }
+
+ html {
+ background-color: #0C323D;
+ color: #809089;
+ font-family: monospace;
+ }
+
+ body {
+ max-width: 700px;
+ }
+
+ p {
+ margin: 0;
+ width: 1%;
+ padding: 0 1%;
+ font-size: 16px;
+ line-height: 1.5;
+ float: left;
+ }
+
+ .input p {
+ margin-right: 1%;
+ }
+
+ .output p {
+ width: 100%;
+ }
+
+ .input input {
+ width: 96%;
+ float: left;
+ border: none;
+ font-size: 16px;
+ line-height: 1.5;
+ font-family: monospace;
+ padding: 0;
+ background: #0C323D;
+ color: #809089;
+ }
+
+ div {
+ clear: both;
+ }
+
+ &lt;/style&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+
+
+ &lt;/body&gt;
+
+ &lt;script&gt;
+ var geval = eval;
+
+ function createInput() {
+ var inputDiv = document.createElement('div');
+ var inputParas = document.createElement('p');
+ var inputForm = document.createElement('input');
+
+ inputDiv.setAttribute('class','input');
+ inputParas.textContent = '&gt;';
+ inputDiv.appendChild(inputParas);
+ inputDiv.appendChild(inputForm);
+ document.body.appendChild(inputDiv);
+ inputDiv.focus();
+
+ inputForm.addEventListener('change', executeCode);
+ }
+
+ function executeCode(e) {
+ try {
+ var result = geval(e.target.value);
+ } catch(e) {
+ var result = 'error — ' + e.message;
+ }
+
+ var outputDiv = document.createElement('div');
+ var outputParas = document.createElement('p');
+
+ outputDiv.setAttribute('class','output');
+ outputParas.textContent = 'Result: ' + result;
+ outputDiv.appendChild(outputParas);
+ document.body.appendChild(outputDiv);
+
+ e.target.disabled = true;
+ e.target.parentNode.style.opacity = '0.5';
+
+ createInput()
+ }
+
+ createInput();
+
+ &lt;/script&gt;
+&lt;/html&gt;</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Hidden_code', '100%', 300) }}</p>
+
+<p>Сначала давайте посмотрим на арифметические операторы, например:</p>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">Оператор</th>
+ <th scope="col">Имя</th>
+ <th scope="col">Пример</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><code>+</code></td>
+ <td>Сложение</td>
+ <td><code>6 + 9</code></td>
+ </tr>
+ <tr>
+ <td><code>-</code></td>
+ <td>Вычитание</td>
+ <td><code>20 - 15</code></td>
+ </tr>
+ <tr>
+ <td><code>*</code></td>
+ <td>Умножение</td>
+ <td><code>3 * 7</code></td>
+ </tr>
+ <tr>
+ <td><code>/</code></td>
+ <td>Деление</td>
+ <td><code>10 / 5</code></td>
+ </tr>
+ </tbody>
+</table>
+
+<p>Вы также можете использовать оператор <code>+</code> для сложения строк текста (в программировании это называется конкатенацией). Попробуйте ввести следующие строки:</p>
+
+<pre class="brush: js notranslate">var name = 'Bingo';
+name;
+var hello = ' says hello!';
+hello;
+var greeting = name + hello;
+greeting;</pre>
+
+<p>Также есть сокращенные операторы, называемые расширенными операторами присваивания. Например, если вы просто хотите добавить новую строку к существующей и вернуть результат, вы можете сделать так:</p>
+
+<pre class="brush: js notranslate">name += ' says hello!';</pre>
+
+<p>Это эквивалентно этому:</p>
+
+<pre class="brush: js notranslate">name = name + ' says hello!';</pre>
+
+<p>Когда мы запускаем проверку true/false (истина/ложь) (например, внутри условных выражений — смотри {{anch("Conditionals", "ниже")}}), мы используем операторы сравнения, например:</p>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">Оператор</th>
+ <th scope="col">Имя</th>
+ <th scope="col">Пример</th>
+ </tr>
+ <tr>
+ <td><code>===</code></td>
+ <td>Строгое равенство (это точно одно и то же?)</td>
+ <td><code>5 === 2 + 4</code></td>
+ </tr>
+ <tr>
+ <td><code>!==</code></td>
+ <td>Строгое неравенство (это не одно и то же?)</td>
+ <td><code>'Chris' !== 'Ch' + 'ris'</code></td>
+ </tr>
+ <tr>
+ <td><code>&lt;</code></td>
+ <td>Меньше чем</td>
+ <td><code>10 &lt; 6</code></td>
+ </tr>
+ <tr>
+ <td><code>&gt;</code></td>
+ <td>Больше чем</td>
+ <td><code>10 &gt; 20</code></td>
+ </tr>
+ </thead>
+</table>
+
+<h3 id="Условные_выражения_Conditionals">Условные выражения (Conditionals)</h3>
+
+<p>Вернемся к нашей функции <code>checkGuess()</code>, я думаю, можно с уверенностью сказать, что мы не хотим, чтобы она просто выводила сообщение заполнитель. Мы хотим, чтобы она проверяла сделал игрок правильный выбор или нет, и соответсвующе реагировала.</p>
+
+<p>Теперь, заменим вашу текущую функцию<code>checkGuess()</code> на эту версию:</p>
+
+<pre class="brush: js notranslate">function checkGuess() {
+ var userGuess = Number(guessField.value);
+ if (guessCount === 1) {
+ guesses.textContent = 'Previous guesses: ';
+ }
+ guesses.textContent += userGuess + ' ';
+
+ if (userGuess === randomNumber) {
+ lastResult.textContent = 'Congratulations! You got it right!';
+ lastResult.style.backgroundColor = 'green';
+ lowOrHi.textContent = '';
+ setGameOver();
+ } else if (guessCount === 10) {
+ lastResult.textContent = '!!!GAME OVER!!!';
+ setGameOver();
+ } else {
+ lastResult.textContent = 'Wrong!';
+ lastResult.style.backgroundColor = 'red';
+ if(userGuess &lt; randomNumber) {
+ lowOrHi.textContent = 'Last guess was too low!';
+ } else if(userGuess &gt; randomNumber) {
+ lowOrHi.textContent = 'Last guess was too high!';
+ }
+ }
+
+ guessCount++;
+ guessField.value = '';
+ guessField.focus();
+}</pre>
+
+<p>Как много кода — фу! Давайте отдельно рассмотрим каждый раздел и объясним, что он делает.</p>
+
+<ul>
+ <li>Первая строка (строка под номером 2 в коде выше) объявляет переменную с именем <code>userGuess</code> и устанавливает ее значение на то, что сейчас введено в текстовое поле. Мы также пропускаем это значение через встроенный метод <code>Number()</code>, чтобы убедится, что значение точно является числом.</li>
+ <li>Затем мы сталкиваемся с нашим первым блоком условного кода (строки 3–5 в коде выше). Блок условного кода позволяет выборочно запускать код в зависимости от того, является определенное условие истинным или нет. Он немного похож на функцию, но это не так. Простейшая форма условного блока начинается с ключевого слова <code>if</code>, за ним круглые скобки, за ними еще фигурные скобки. В круглые скобки мы добавляем проверку. Если проверка возвращает <code>true</code>, запускается код в фигурных скобках. Если нет, этот код пропускается и мы переходим к следующей части кода. В этом случае проверяется равна ли переменая <code>guessCount</code> числу <code>1</code> (то есть является ли это первой попыткой игрока или нет):
+ <pre class="brush: js notranslate">guessCount === 1</pre>
+ Если это так, мы выводим параграф с содержанием "Previous guesses: ". Если нет, ничего не делаем.</li>
+ <li>Строка 6 добавяет текущее знаение <code>userGuess</code>  в конец параграфа <code>guesses</code>, плюс пустое пространство поэтому между каждыми показанными предположениями будет пробел.</li>
+ <li>Следующий блок (строки 8–24 ) делает несколько проверок:
+ <ul>
+ <li><code><font face="Open Sans, arial, x-locale-body, sans-serif"><span style="background-color: #ffffff;">Первая конструкция  </span></font>if(){ }</code> проверяет, совпадает ли предположение пользователя с <code>randomNumber</code> установленному в верхней части нашего JavaScript. Если это так, игрок правильно догадался, и игра выиграна, поэтому мы показываем игроку поздравительное сообщение с приятным зеленым цветом, очищаем содержимое окна информации о минимуме / максимуме и запускаем функцию, называемую setGameOver (), которую мы обсудим позже.</li>
+ <li>Теперь мы добавили еще одну проверку после пердыдущей, используя конструкцию else if () {}. Эта конструкция проверяет, является ли этот ход последним ходом пользователя. Если это так, программа выполняет то же самое, что и в предыдущем блоке, но выведет сообщение с текстом GAME OVER.</li>
+ <li>Последний блок, в конце нашего кода (else {}), содержит код, который запускается только в том случае, если ни один из двух других тестов не возвращает true (т. е. Игрок не догадался правильно, но у него еще остались  догадки). В этом случае мы говорим игроку, что он ошибся, затем мы выполняем еще один условный тест, чтобы проверить, было ли предположение больше или меньше ответа, показывая дополнительное сообщение.</li>
+ </ul>
+ </li>
+ <li>Последние три строки в функции (строки 26–28 ) готовят нас к следующей попытке. Мы добавляем 1 к переменной <code>guessCount</code>  так как игрок использовал свой ход (<code>++</code> оператор инкремента — увеличивает на 1), очищаем значение текстового поля и фокусируемся на нем снова,  готовы для ввода следующего ответа.</li>
+</ul>
+
+<h3 id="События_Events">События (Events)</h3>
+
+<p><span id="result_box" lang="ru"><span>На данный момент у нас есть хорошо реализованная функция <code>checkGuess()</code>, но она ничего не сделает, потому что мы еще не вызвали ее.</span> <span>В идеале мы хотим вызывать её во время нажатия кнопки «</span></span> Submit guess <span lang="ru"><span>», и для этого нам нужно использовать событие.</span> <span>События - это действия, которые происходят в браузере, например, нажатие кнопки или загрузка страницы или воспроизведение видео, в ответ на которые мы можем запускать блоки кода.</span> <span>Конструкции, которые прослушивают событие, называются <strong>прослушивателями событий</strong>, а блоки кода, выполняемые в ответ на срабатывание событий, называются <strong>обработчиками событий</strong>.</span></span></p>
+
+<p><span id="result_box" lang="ru"><span>Добавьте следующую строку ниже закрывающей фигурной скобки функции <code>checkGuess()</code>:</span></span></p>
+
+<pre class="brush: js notranslate">guessSubmit.addEventListener('click', checkGuess);</pre>
+
+<p><span id="result_box" lang="ru"><span>Здесь мы добавляем прослушиватель событий к кнопке <code>guessSubmit</code>.</span> <span>Это метод, который принимает два входных значения (называемые аргументами) - тип события, которое мы выслушиваем (в данном случае <code>click</code>) в виде строки, и код, который мы хотим запустить при возникновении события (в данном случае</span> <span>функция <code>checkGuess()</code> - обратите внимание, что нам не нужно указывать круглые скобки при записи внутри</span></span> {{domxref("EventTarget.addEventListener", "addEventListener()")}}).</p>
+
+<p><span id="result_box" lang="ru"><span>Попробуйте сохранить и обновить код сейчас, и ваш пример должен теперь работать, но до определенного момента.</span> <span>Единственная проблема в том, что если вы угадаете правильный ответ или исчерпаете догадки, игра сломается, потому что мы еще не определили функцию <code>setGameOver()</code>, которая должна запускаться после завершения игры.</span> <span>Давайте добавим наш недостающий код и завершим пример функциональности.</span></span></p>
+
+<h3 id="Завершение_игры">Завершение игры</h3>
+
+<p><span id="result_box" lang="ru"><span>Давайте добавим функцию <code>setGameOver()</code> в конец нашего кода, а затем пройдем по ней.</span> <span>Добавьте это под нижней частью вашего JavaScript:</span></span></p>
+
+<pre class="brush: js notranslate">function setGameOver() {
+ guessField.disabled = true;
+ guessSubmit.disabled = true;
+ resetButton = document.createElement('button');
+ resetButton.textContent = 'Start new game';
+ document.body.appendChild(resetButton);
+ resetButton.addEventListener('click', resetGame);
+}</pre>
+
+<ul>
+ <li><span id="result_box" lang="ru"><span>Первые две строки отключают ввод текста и кнопку формы, устанавливая их отключенные свойства как <code>true</code>.</span> <span>Это необходимо, потому что, если бы мы этого не сделали, пользователь мог бы представить больше догадок после завершения игры, что испортит ситуацию.</span></span></li>
+ <li><span id="result_box" lang="ru"><span>Следующие три строки генерируют новый элемент {{htmlelement("button")}}, устанавливают его текстовую метку «</span></span> Start new game<span lang="ru"><span>» и добавляют ее к нижней части нашего HTML.</span></span></li>
+ <li><span id="result_box" lang="ru"><span>Последняя строка устанавливает прослушиватель событий на нашей новой кнопке, так что при нажатии на нее запускается функция <code>resetGame()</code>.</span></span></li>
+</ul>
+
+<p><span id="result_box" lang="ru"><span>Теперь нам нужно также определить эту функцию!</span> <span>Добавьте следующий код, снова в нижнюю часть вашего JavaScript:</span></span></p>
+
+<pre class="brush: js notranslate">function resetGame() {
+ guessCount = 1;
+
+ var resetParas = document.querySelectorAll('.resultParas p');
+ for (var i = 0 ; i &lt; resetParas.length ; i++) {
+ resetParas[i].textContent = '';
+ }
+
+ resetButton.parentNode.removeChild(resetButton);
+
+ guessField.disabled = false;
+ guessSubmit.disabled = false;
+ guessField.value = '';
+ guessField.focus();
+
+ lastResult.style.backgroundColor = 'white';
+
+ randomNumber = Math.floor(Math.random() * 100) + 1;
+}</pre>
+
+<p><span id="result_box" lang="ru"><span>Этот довольно длинный блок кода полностью сбрасывает все на то, как это было в начале игры, поэтому у игрока может быть еще один ход.</span> <span>Это:</span></span></p>
+
+<ul>
+ <li>Устанавливает значение <code>guessCount</code> на 1.</li>
+ <li><span class="short_text" id="result_box" lang="ru"><span>Удаляет все пункты информации</span></span>.</li>
+ <li><span class="short_text" id="result_box" lang="ru"><span>Удаляет кнопку сброса из нашего кода.</span></span></li>
+ <li>Включает элементы формы, устанавливает фокус, делает поле доступным для следующих угадываний.</li>
+ <li><span class="short_text" id="result_box" lang="ru"><span>Удаляет цвет фона из абзаца <code>lastResult</code>.</span></span></li>
+ <li><span id="result_box" lang="ru"><span>Создает новое случайное число, чтобы вы не угадывали одно и тоже!</span></span></li>
+</ul>
+
+<p><strong><span id="result_box" lang="ru"><span>С этого момента у вас есть </span></span><span id="result_box" lang="ru"><span>полностью работающая (простая) игра - поздравляем!</span></span></strong> <span lang="ru"><span> </span></span></p>
+
+<p><span id="result_box" lang="ru"><span>Все, что нам осталось сделать в этой статье, - это поговорить о нескольких других важных функциях кода, которые вы уже видели, хотя вы, возможно, этого не осознали.</span></span></p>
+
+<h3 id="Циклы_Loops">Циклы (Loops) </h3>
+
+<div class="_Ejb">
+<div id="tw-target">
+<div class="tw-nfl tw-compact-ta-container" id="tw-target-text-container">Одна часть вышеприведенного кода, которую мы должны рассмотреть более подробно, - это цикл for. Циклы - очень важная концепция программирования, которая позволяет вам снова и снова запускать кусок кода, пока не будет выполнено определенное условие.</div>
+
+<div class="tw-nfl tw-compact-ta-container">Для начала перейдите в панель инструментов разработчика JavaScript-консоли и введите следующее:</div>
+</div>
+</div>
+
+<pre class="brush: js notranslate">for (var i = 1 ; i &lt; 21 ; i++) { console.log(i) }</pre>
+
+<p><span lang="ru">Что случилось? Номера с 1 по 20 были напечатаны в консоли. Это из-за цикла. Цикл for принимает три входных значения (аргументы):</span><br>
+ <span lang="ru">Начальное значение: в этом случае мы начинаем подсчет c 1, но это может быть любое число которое вам нравится. Вы можете заменить i любым другим именем, которое вам нравится, но я использую его как условность, потому что оно короткое и легко запоминается. Условие выхода: Здесь мы указали i &lt;21 - цикл будет продолжаться до тех пор, пока i будет меньше 21. Когда i достигнет 21, цикл больше не будет работать. Инкремент: мы указали i ++, что означает «увеличить i на 1». Цикл будет выполняться один раз для каждого значения i, пока оно не достигнет значения 21 (как обсуждалось выше). В этом случае мы просто печатаем значение i в консоли на каждой итерации с помощью {{domxref ("Console.log", "console.log ()")}}.</span></p>
+
+<p><span lang="ru">Теперь давайте посмотрим на цикл в нашей игре угадывания чисел - в функции resetGame () можно найти следующее:</span></p>
+
+<pre class="brush: js notranslate">var resetParas = document.querySelectorAll('.resultParas p');
+for (var i = 0 ; i &lt; resetParas.length ; i++) {
+ resetParas[i].textContent = '';
+}</pre>
+
+<p><span lang="ru">Этот код создает переменную, содержащую список всех абзацев внутри &lt;div class = "resultParas"&gt;, используя метод {{domxref ("Document.querySelectorAll", "querySelectorAll ()")}}, затем он проходит через каждый из них, удаляя текстовое содержимое каждого из них.</span></p>
+
+<h3 id="Немного_об_объектах_Objects">Немного об объектах (Objects)</h3>
+
+<p>Давайте добавим еще одно окончательное улучшение, прежде чем перейти к обсуждению. Добавьте следующую строку чуть ниже <code>var resetButton;</code> в верхней части вашего JavaScript, затем сохраните файл:</p>
+
+<pre class="brush: js notranslate">guessField.focus();</pre>
+
+<p>Эта строка использует метод {{domxref("HTMLElement.focus", "focus()")}}, чтобы автоматически помещать текстовый курсор в текстовое поле {{htmlelement("input")}}, как только загрузится страница. Пользователь сможет сразу набрать свою первую догадку, не нажимая поле формы. Это всего лишь небольшое дополнение, но оно улучшает удобство использования - дает пользователю хорошую визуальную подсказку относительно того, что они должны делать в игре.</p>
+
+<p>Давайте проанализируем, что произошло. В JavaScript все элементы являются объектами. Объект - это набор связанных функций, хранящихся в одной группе<em>. </em>Вы можете создавать собственные объекты, но это требует мастерства, и мы не хотели бы раскрывать эту тему в рамках данного курса. Будет достаточно обсудить встроенные объекты вашего браузера, которые позволяют реализовывать множество полезных вещей.</p>
+
+<p>В нашем примере мы сначала создали переменную <code>guessField</code>, которая запоминает значение из поля ввода в нашем HTML - следующая строка находится среди первых в нашем коде:</p>
+
+<pre class="brush: js notranslate">var guessField = document.querySelector('.guessField');</pre>
+
+<p>Чтобы получить это значение, мы использовали метод {{domxref("document.querySelector", "querySelector()")}} объекта {{domxref("document")}}. <code>querySelector()</code> "берет" одну часть информации -  <a href="/en-US/docs/Learn/CSS/Introduction_to_CSS/Selectors">CSS selector</a>, который выбирает нужный элемент<em>.</em></p>
+
+<p>Поскольку <code>guessField</code> теперь содержит ссылку на элемент {{htmlelement("input")}}, теперь он будет иметь доступ к ряду свойств (в основном к переменным, хранящимся внутри объектов, некоторые значения которых нельзя изменять) и методы (в основном функции, хранящиеся внутри объектов). Одним из методов, доступных для ввода элементов, является focus (), поэтому мы можем теперь использовать эту строку для фокусировки ввода текста:</p>
+
+<pre class="brush: js notranslate">guessField.focus();</pre>
+
+<p>Для переменных, которые не содержат ссылок на элементы формы, не будет доступен <code>focus()</code>. Например, переменная <code>guesses</code> содержит ссылку на элемент {{htmlelement ("p")}}, а <code>guessCount</code> содержит число.</p>
+
+<h3 id="Поиграем_с_объектами_браузера">Поиграем с объектами браузера</h3>
+
+<p>Давайте немного поиграем с некоторыми объектами браузера.</p>
+
+<ol>
+ <li>Для начала запустите свою программу в браузере.</li>
+ <li>Далее, откройте <a href="/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools">инструменты разработчика в вашем браузере</a>, и убедитесь, что вы перешли во вкладку с консолью JavaScript.</li>
+ <li>Введите <code>guessField</code> и консоль покажет, что переменная содержит элемент {{htmlelement("input")}}. Вы также можете заметить, что консоль автоматически заполняет имена объектов, которые существуют внутри исполняющей среды, включая ваши переменные!</li>
+ <li>Теперь введите следующее:
+ <pre class="brush: js notranslate">guessField.value = 'Hello';</pre>
+ Свойство <code>value</code> представляет текущее значение, введенное в текстовое поле. Заметьте, что, введя эту команду, мы изменили его!</li>
+ <li>Попробуйте ввести <code>guesses</code> и нажать return. Консоль покажет, что в переменной содержится элемент {{htmlelement("p")}}.</li>
+ <li>Теперь попробуйте ввести:
+ <pre class="brush: js notranslate">guesses.value</pre>
+ Браузер вернет вам <code>undefined</code>, потому что <code>value</code> не существует в параграфах.</li>
+ <li>Для изменения текста внутри параграфа, взамен используйте свойство {{domxref("Node.textContent", "textContent")}}. Попробуйте:
+ <pre class="brush: js notranslate">guesses.textContent = 'Where is my paragraph?';</pre>
+ </li>
+ <li>Теперь немного повеселимся. Попробуйте ввести следующие строки, одну за другой:
+ <pre class="brush: js notranslate">guesses.style.backgroundColor = 'yellow';
+guesses.style.fontSize = '200%';
+guesses.style.padding = '10px';
+guesses.style.boxShadow = '3px 3px 6px black';</pre>
+ Каждый элемент на странице имеет свойство <code>style</code>, которое само по себе содержит объект, свойства которого содержат все встроенные стили CSS, применяемые к этому элементу. Это позволяет нам динамически задавать новые стили CSS для элементов с помощью JavaScript.</li>
+</ol>
+
+<h2 id="Теперь_можно_отдохнуть...">Теперь можно отдохнуть...</h2>
+
+<p>Итак, на этом пример закончился - отлично, вы добрались до конца! Попробуйте свой финальный код или <a href="http://mdn.github.io/learning-area/javascript/introduction-to-js-1/first-splash/number-guessing-game.html">поиграйте с нашей готовой версией здесь</a>. Если вы не можете запустить этот пример, сверьтесь с <a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/first-splash/number-guessing-game-start.html">исходным кодом.</a></p>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/What_is_JavaScript", "Learn/JavaScript/Первые_шаги/Что_пошло_не_так", "Learn/JavaScript/Первые_шаги")}}</p>
diff --git a/files/ru/learn/javascript/первые_шаги/arrays/index.html b/files/ru/learn/javascript/первые_шаги/arrays/index.html
new file mode 100644
index 0000000000..7f38ce4a50
--- /dev/null
+++ b/files/ru/learn/javascript/первые_шаги/arrays/index.html
@@ -0,0 +1,678 @@
+---
+title: Массивы
+slug: Learn/JavaScript/Первые_шаги/Arrays
+tags:
+ - JavaScript
+ - Pop
+ - Push
+ - shift
+ - unshift
+ - Для начинающих
+ - Массивы
+ - Статья
+translation_of: Learn/JavaScript/First_steps/Arrays
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/Useful_string_methods", "Learn/JavaScript/Первые_шаги/Создатель_глуых_историй", "Learn/JavaScript/Первые_шаги")}}</div>
+
+<p class="summary">В финальной статье этого раздела, мы познакомимся с массивами — лаконичным способом хранения списка элементов под одним именем. Мы поймем, чем они полезны, затем узнаем, как создать массив, получить, добавить и удалить элементы, хранящиеся в массиве.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Необходимые навыки:</th>
+ <td>Базовая компьютерная грамотность, базовое понимание HTML и CSS, понимание о том, что такое JavaScript.</td>
+ </tr>
+ <tr>
+ <th scope="row">Цель:</th>
+ <td>Понять, что такое массивы и как использовать их в JavaScript.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Что_такое_массив">Что такое массив?</h2>
+
+<p>Массивы обычно описываются как «объекты, подобные спискам»; они представляют собой в основном отдельные объекты, которые содержат несколько значений, хранящихся в списке. Объекты массива могут храниться в переменных и обрабатываться во многом так же, как и любой другой тип значения, причем разница заключается в том, что мы можем получить доступ к каждому значению внутри списка отдельно и делать супер полезные и эффективные вещи со списком, а также делать то же самое для каждого из значений. Представим, что у нас есть список продуктов и их цены, хранящиеся в массиве, и мы хотим их просмотреть и распечатать на счете-фактуре, общая сумма всех цен и распечатка общей цены внизу.</p>
+
+<p>Если бы у нас не было массивов, мы должны были бы хранить каждый элемент в отдельной переменной, а затем вызывать код, выполняющий печать и добавляющий отдельно каждый элемент. Написание такого кода займет намного больше времени, сам код будет менее эффективным и подверженным  ошибкам. Если бы у нас было 10 элементов для добавления в счет-фактуру, это еще куда ни шло, но как насчет 100 предметов? Или 1000? Мы вернемся к этому примеру позже в статье.</p>
+
+<p><span id="result_box" lang="ru"><span>Как и в предыдущих статьях, давайте узнаем о реальных основах массивов, введя некоторые примеры в консоль JavaScript.</span> <span>Мы предоставили один ниже (вы также можете</span></span> <a href="https://mdn.github.io/learning-area/javascript/introduction-to-js-1/variables/index.html">open this console</a> в отдельном окне, или использовать <a href="/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools">browser developer console</a>, если вам угодно).</p>
+
+<div class="hidden">
+<h6 id="Спрятанный_код">Спрятанный код</h6>
+
+<pre class="brush: html">&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+ &lt;head&gt;
+ &lt;meta charset="utf-8"&gt;
+ &lt;title&gt;JavaScript console&lt;/title&gt;
+ &lt;style&gt;
+ * {
+ box-sizing: border-box;
+ }
+
+ html {
+ background-color: #0C323D;
+ color: #809089;
+ font-family: monospace;
+ }
+
+ body {
+ max-width: 700px;
+ }
+
+ p {
+ margin: 0;
+ width: 1%;
+ padding: 0 1%;
+ font-size: 16px;
+ line-height: 1.5;
+ float: left;
+ }
+
+ .input p {
+ margin-right: 1%;
+ }
+
+ .output p {
+ width: 100%;
+ }
+
+ .input input {
+ width: 96%;
+ float: left;
+ border: none;
+ font-size: 16px;
+ line-height: 1.5;
+ font-family: monospace;
+ padding: 0;
+ background: #0C323D;
+ color: #809089;
+ }
+
+ div {
+ clear: both;
+ }
+
+ &lt;/style&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+
+
+ &lt;/body&gt;
+
+ &lt;script&gt;
+ var geval = eval;
+ function createInput() {
+ var inputDiv = document.createElement('div');
+ var inputPara = document.createElement('p');
+ var inputForm = document.createElement('input');
+
+ inputDiv.setAttribute('class','input');
+ inputPara.textContent = '&gt;';
+ inputDiv.appendChild(inputPara);
+ inputDiv.appendChild(inputForm);
+ document.body.appendChild(inputDiv);
+
+ if(document.querySelectorAll('div').length &gt; 1) {
+        inputForm.focus();
+      }
+
+ inputForm.addEventListener('change', executeCode);
+ }
+
+ function executeCode(e) {
+ try {
+ var result = geval(e.target.value);
+ } catch(e) {
+ var result = 'error — ' + e.message;
+ }
+
+ var outputDiv = document.createElement('div');
+ var outputPara = document.createElement('p');
+
+ outputDiv.setAttribute('class','output');
+ outputPara.textContent = 'Result: ' + result;
+ outputDiv.appendChild(outputPara);
+ document.body.appendChild(outputDiv);
+
+ e.target.disabled = true;
+ e.target.parentNode.style.opacity = '0.5';
+
+ createInput()
+ }
+
+ createInput();
+
+ &lt;/script&gt;
+&lt;/html&gt;</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Hidden_code', '100%', 300) }}</p>
+
+<h3 id="Создание_массива">Создание массива</h3>
+
+<p>Массивы создаются из квадратных скобок , которые содержат список элементов, разделённых запятыми.</p>
+
+<ol>
+ <li>Допустим, мы бы хотели хранить список покупок в массиве — мы бы сделали что-то вроде этого. Введите следующие строчки в вашу консоль:
+ <pre class="brush: js">var shopping = ['bread', 'milk', 'cheese', 'hummus', 'noodles'];
+shopping;</pre>
+ </li>
+ <li>В данном случае, каждый элемент в массиве — это строка , но имейте в виду, что вы можете хранить любой элемент в массиве — строку, число, объект, другую переменную, даже другой массив. Вы также можете перемешивать типы элементов — они не должны все быть числами, строками, и так далее. Попробуйте это:
+ <pre class="brush: js">var sequence = [1, 1, 2, 3, 5, 8, 13];
+var random = ['tree', 795, [0, 1, 2]];</pre>
+ </li>
+ <li>Попробуйте сами создать несколько массивов, перед тем как двигаться дальше.</li>
+</ol>
+
+<h3 id="Получение_и_изменение_элементов_массива">Получение и изменение элементов массива</h3>
+
+<p>Вы можете после этого получать доступ к отдельным элементам в массиве, используя квадратные скобки, таким же способом каким вы <a href="/en-US/Learn/JavaScript/First_steps/Useful_string_methods#Retrieving_a_specific_string_character">получаете доступ к буквам в строке</a>.</p>
+
+<ol>
+ <li>Введите следующее в вашу консоль:
+ <pre class="brush: js">shopping[0];
+// возвращает "bread"</pre>
+ </li>
+ <li>Вы также можете изменять элемент в массиве, просто дав отдельному элементу массива новое значение. Попробуйте это:
+ <pre class="brush: js">shopping[0] = 'tahini';
+shopping;
+// shopping теперь возвратит [ "tahini", "milk", "cheese", "hummus", "noodles" ]</pre>
+
+ <div class="note"><strong>Заметка</strong>: Мы уже упоминали это прежде, но просто как напоминание — компьютеры начинают считать с нуля!</div>
+ </li>
+ <li>Заметьте, что массив внутри массива называется многомерным массивом. <span id="result_box" lang="ru"><span>Вы можете получить доступ к элементу внутри массива, который сам находится внутри другого массива, объединив два набора квадратных скобок.</span> <span>Например, для доступа к одному из элементов внутри массива, который является третьим элементом внутри массива <code>random </code>(см. предыдущую секцию данной статьи), мы могли бы сделать что-то вроде этого:</span></span>
+ <pre class="brush: js">random[2][2];</pre>
+ </li>
+ <li>Попробуйте внести некоторые дополнительные изменения в свои примеры массивов, прежде чем двигаться дальше.</li>
+</ol>
+
+<h3 id="Нахождение_длины_массива">Нахождение длины массива</h3>
+
+<p>Вы можете найти длину массива (количество элементов в нём) точно таким же способом, как вы находите длину строки (в символах) — используя свойство {{jsxref("Array.prototype.length","length")}}. Попробуйте следующее:</p>
+
+<pre class="brush: js">sequence.length;
+// должно возвратить 7</pre>
+
+<p>Это свойство имеет и другие применения, но чаще всего используется, чтобы сказать, что цикл продолжается, пока он не зациклится на всех элементах массива. Так, например:</p>
+
+<pre class="brush: js">var sequence = [1, 1, 2, 3, 5, 8, 13];
+for (var i = 0; i &lt; sequence.length; i++) {
+ console.log(sequence[i]);
+}</pre>
+
+<p><span id="result_box" lang="ru"><span>В будущих статьях вы узнаете о циклах, но вкратце этот код говорит:</span></span></p>
+
+<ol>
+ <li><span class="short_text" id="result_box" lang="ru"><span>Начать цикл с номера позиции 0 в массиве.</span></span></li>
+ <li>Остановить цикл на номере элемента, равном длине массива. Это будет работать для массива любой длины, но в этом случае он остановит цикл на элементе номер 7 (это хорошо, поскольку последний элемент, который мы хотим, чтобы цикл был закрыт, равен 6).</li>
+ <li><span id="result_box" lang="ru"><span>Для каждого элемента вернуть его значение в консоли браузера с помощью</span></span> <code><a href="/en-US/docs/Web/API/Console/log">console.log()</a></code>.</li>
+</ol>
+
+<h2 id="Некоторые_полезные_методы_массивов">Некоторые полезные методы массивов</h2>
+
+<p><span id="result_box" lang="ru"><span>В этом разделе мы рассмотрим некоторые полезные методы, связанные с массивом, которые позволяют нам разбивать строки на элементы массива и наоборот, а также добавлять новые элементы в массивы.</span></span></p>
+
+<h3 id="Преобразование_между_строками_и_массивами"><span class="short_text" id="result_box" lang="ru"><span>Преобразование между строками и массивами</span></span></h3>
+
+<p>Часто у Вас могут быть некоторые необработанные данные, содержащиеся в большой длинной строке, и вы можете захотеть разделить полезные пункты до более удобной и полезной формы, а затем сделать что-то для них, например отобразить их в таблице данных. Для этого мы можем использовать метод {{jsxref ("String.prototype.split ()", "split ()")}}. В его простейшей форме он принимает единственный параметр, символ, который вы хотите отделить в строке, и возвращает подстроки между разделителем как элементы в массиве.</p>
+
+<div class="note">
+<p><strong>Заметка</strong>: Хорошо, технически это строковый метод, не метод массива, <span id="result_box" lang="ru"><span>но мы поместили его в массивы, так как он хорошо подходит для них.</span></span></p>
+</div>
+
+<ol>
+ <li>Поиграем с этим, посмотрим как это работает. Сначала, создадим строку в вашей консоли:
+ <pre class="brush: js">var myData = 'Manchester,London,Liverpool,Birmingham,Leeds,Carlisle';</pre>
+ </li>
+ <li>Теперь разделим ee посредством запятой:
+ <pre class="brush: js">var myArray = myData.split(',');
+myArray;</pre>
+ </li>
+ <li>Наконец, попробуйте найти длину вашего нового массива и извлечь из него некоторые элементы:
+ <pre class="brush: js">myArray.length;
+myArray[0]; // первый элемент в массиве
+myArray[1]; // второй элемент в массиве
+myArray[myArray.length-1]; // последний элемент в массиве</pre>
+ </li>
+ <li>Вы можете сделать обратное используя метод{{jsxref("Array.prototype.join()","join()")}} . Попробуйте следующее:
+ <pre class="brush: js">var myNewString = myArray.join(',');
+myNewString;</pre>
+ </li>
+ <li> Другой способ преобразования массива в строку - использовать метод {{jsxref("Array.prototype.toString()","toString()")}} . <code>toString() ,</code>возможно, проще,чем <code>join()</code> поскольку он не принимает параметр, но это ограничивает его. С <code>join()</code>вы можете указать разные разделители (попробуйте выполнить шаг 4 с другим символом, кроме запятой).
+ <pre class="brush: js">var dogNames = ["Rocket","Flash","Bella","Slugger"];
+dogNames.toString(); //Rocket,Flash,Bella,Slugger</pre>
+ </li>
+</ol>
+
+<h3 id="Добавление_и_удаление_элементов_массива">Добавление и удаление элементов массива</h3>
+
+<p>Мы еще не рассмотрели добавление и удаление элементов массива - давайте посмотрим на это сейчас. Мы будем использовать массив <code>myArray</code> , с которым мы столкнулись в предыдущем разделе. Если вы еще не прошли этот раздел, сначала создайте массив в консоли:</p>
+
+<pre class="brush: js">var myArray = ['Manchester', 'London', 'Liverpool', 'Birmingham', 'Leeds', 'Carlisle'];</pre>
+
+<p>Прежде всего, чтобы добавить или удалить элемент с конца массива, мы можем использовать {{jsxref("Array.prototype.push()","push()")}} и {{jsxref("Array.prototype.pop()","pop()")}} соответственно.</p>
+
+<ol>
+ <li>Давайте сначала используем метод <code>push()</code> — заметьте, что вам нужно указать один или более элементов, которые вы хотите добавить в конец своего массива. Попробуйте это:
+
+ <pre class="brush: js">myArray.push('Cardiff');
+myArray;
+myArray.push('Bradford', 'Brighton');
+myArray;
+</pre>
+ </li>
+ <li>При завершении вызова метода возвращается новая длина массива. Если бы вы хотели сохранить новую длину массива в переменной, вы бы могли сделать что-то вроде этого:
+ <pre class="brush: js">var newLength = myArray.push('Bristol');
+myArray;
+newLength;</pre>
+ </li>
+ <li>Удаление последнего элемента массива можно совершить с помощью вызова метода <code>pop()</code>. Попробуйте это:
+ <pre class="brush: js">myArray.pop();</pre>
+ </li>
+ <li>Когда вызов метода завершается, возвращается удалённый элемент. Вы бы могли также сделать такое:
+ <pre class="brush: js">var removedItem = myArray.pop();
+myArray;
+removedItem;</pre>
+ </li>
+</ol>
+
+<p>{{jsxref("Array.prototype.unshift()","unshift()")}} и {{jsxref("Array.prototype.shift()","shift()")}} работают точно таким же способом, за исключением того что они работают в начале массива, а не в конце.</p>
+
+<ol>
+ <li>Сначала, попробуем метод <code>unshift()</code>:
+
+ <pre class="brush: js">myArray.unshift('Edinburgh');
+myArray;</pre>
+ </li>
+ <li>Теперь <code>shift()</code>; попробуйте эти!
+ <pre class="brush: js">var removedItem = myArray.shift();
+myArray;
+removedItem;</pre>
+ </li>
+</ol>
+
+<h2 id="Практика_Печать_продуктов!">Практика: Печать продуктов!</h2>
+
+<p>Вернемся к описанному выше примеру - распечатываем названия продуктов и цен на счет-фактуру, затем суммируем цены и печатаем их внизу. В приведенном ниже редактируемом примере есть комментарии, содержащие числа - каждая из этих отметок является местом, где вы должны добавить что-то в код. Они заключаются в следующем:</p>
+
+<ol>
+ <li>Ниже комментария <code>// number 1</code>  имеется ряд строк, каждая из которых содержит название продукта и цену, разделенные двоеточием. Нужно превратить их в массив и сохранить его  под названием  <code>products</code>.</li>
+ <li>На строке с комментарием <code>// number 2</code>  начинается цикл for. В строке цикла имеется<code> i &lt;= 0</code>, что является условием , которое заставляет цикл for выполняться только один раз, так как это значение i сообщает циклу: «останавливаться, когда <code>i</code> меньше или равен 0», при этом <code>i</code> начинается с 0. Нужно заменить <code>i &lt;= 0</code> условным тестом, который останавливает цикл, когда <code>i</code> перестает быть меньше длины массива <code>products</code> .</li>
+ <li>Под комментарием <code>// number 3</code> мы хотим, чтобы вы написали строку кода, которая разбивает текущий элемент массива (<code>name:price</code>) на два отдельных элемента: один содержит только имя, а другой - содержащее только цену. Если не знаете, как это сделать, еще раз просмотрите статью <a href="/ru/docs/Learn/JavaScript/Первые_шаги/Useful_string_methods">Полезные строковые методы</a>, а лучше, посмотрите раздел {{anch("Преобразование между строками и массивами")}} этой статьи.</li>
+ <li>В рамках приведенной выше строки нужно преобразовать цену из строки в число. Если не помните, как это сделать, ознакомьтесь со статьей <a href="/ru/docs/Learn/JavaScript/Первые_шаги/Строки">строки в JavaScript</a>.</li>
+ <li>В верхней части кода есть переменная с именем <code>total</code> , которая содержит значение <code>0</code>. Внутри цикла (под комментарием <code>// number 4</code>) нужно добавить строку, которая добавляет текущую цену товара к этой сумме на каждой итерации цикла, так чтобы в конце кода была выведена корректная сумма в счет-фактуре. Для этого вам может понадобится <a href="/ru/docs/Learn/JavaScript/Первые_шаги/Math#Операторы_присваивания">оператор присваивания</a>.</li>
+ <li>Под комментарием <code>// number 5</code> нужно изменить строку так, чтобы переменная <code>itemText</code> была равна "current item name — $current item price",  например "Shoes — $23.99" для каждого случая, чтобы корректная информация для каждого элемента была напечатана в счете-фактуре. Здесь обычная конкатенация строк, которая должна быть вам знакома.</li>
+</ol>
+
+<div class="hidden">
+<h6 id="Playable_code">Playable code</h6>
+
+<pre class="brush: html">&lt;!-- Не выделяйте тут ничего, не копируйте, не всавляйте!
+  Еле починил --&gt;
+
+&lt;h2&gt;Live output&lt;/h2&gt;
+
+&lt;div class="output" style="min-height: 150px;"&gt;
+
+&lt;ul&gt;
+
+&lt;/ul&gt;
+
+&lt;p&gt;&lt;/p&gt;
+
+&lt;/div&gt;
+
+&lt;h2&gt;Editable code&lt;/h2&gt;
+
+&lt;p class="a11y-label"&gt;Press Esc to move focus away from the code area (Tab inserts a tab character).&lt;/p&gt;
+
+&lt;textarea id="code" class="playable-code" style="height: 410px;width: 95%"&gt;
+var list = document.querySelector('.output ul');
+var totalBox = document.querySelector('.output p');
+var total = 0;
+list.innerHTML = '';
+totalBox.textContent = '';
+// number 1
+ 'Underpants:6.99'
+ 'Socks:5.99'
+ 'T-shirt:14.99'
+ 'Trousers:31.99'
+ 'Shoes:23.99';
+
+for (var i = 0; i &lt;= 0; i++) { // number 2
+ // number 3
+
+ // number 4
+
+ // number 5
+ itemText = 0;
+
+ var listItem = document.createElement('li');
+ listItem.textContent = itemText;
+ list.appendChild(listItem);
+}
+
+totalBox.textContent = 'Total: $' + total.toFixed(2);
+&lt;/textarea&gt;
+
+&lt;div class="playable-buttons"&gt;
+ &lt;input id="reset" type="button" value="Reset"&gt;
+ &lt;input id="solution" type="button" value="Show solution"&gt;
+&lt;/div&gt;
+</pre>
+
+<pre class="brush: js">var textarea = document.getElementById('code');
+var reset = document.getElementById('reset');
+var solution = document.getElementById('solution');
+var code = textarea.value;
+var userEntry = textarea.value;
+
+function updateCode() {
+ eval(textarea.value);
+}
+
+reset.addEventListener('click', function() {
+ textarea.value = code;
+ userEntry = textarea.value;
+ solutionEntry = jsSolution;
+ solution.value = 'Show solution';
+ updateCode();
+});
+
+solution.addEventListener('click', function() {
+ if(solution.value === 'Show solution') {
+ textarea.value = solutionEntry;
+ solution.value = 'Hide solution';
+ } else {
+ textarea.value = userEntry;
+ solution.value = 'Show solution';
+ }
+ updateCode();
+});
+
+var jsSolution = 'var list = document.querySelector(\'.output ul\');\nvar totalBox = document.querySelector(\'.output p\');\nvar total = 0;\nlist.innerHTML = \'\';\ntotalBox.textContent = \'\';\n\nvar products = [\'Underpants:6.99\',\n \'Socks:5.99\',\n \'T-shirt:14.99\',\n \'Trousers:31.99\',\n \'Shoes:23.99\'];\n\nfor(var i = 0; i &lt; products.length; i++) {\n var subArray = products[i].split(\':\');\n var name = subArray[0];\n var price = Number(subArray[1]);\n total += price;\n itemText = name + \' — $\' + price;\n\n var listItem = document.createElement(\'li\');\n listItem.textContent = itemText;\n list.appendChild(listItem);\n}\n\ntotalBox.textContent = \'Total: $\' + total.toFixed(2);';
+var solutionEntry = jsSolution;
+
+textarea.addEventListener('input', updateCode);
+window.addEventListener('load', updateCode);
+
+// stop tab key tabbing out of textarea and
+// make it write a tab at the caret position instead
+
+textarea.onkeydown = function(e){
+ if (e.keyCode === 9) {
+ e.preventDefault();
+ insertAtCaret('\t');
+ }
+
+
+ if (e.keyCode === 27) {
+ textarea.blur();
+ }
+};
+
+function insertAtCaret(text) {
+ var scrollPos = textarea.scrollTop;
+ var caretPos = textarea.selectionStart;
+
+ var front = (textarea.value).substring(0, caretPos);
+ var back = (textarea.value).substring(textarea.selectionEnd, textarea.value.length);
+ textarea.value = front + text + back;
+ caretPos = caretPos + text.length;
+ textarea.selectionStart = caretPos;
+ textarea.selectionEnd = caretPos;
+ textarea.focus();
+ textarea.scrollTop = scrollPos;
+}
+
+// Update the saved userCode every time the user updates the text area code
+
+textarea.onkeyup = function(){
+ // We only want to save the state when the user code is being shown,
+ // not the solution, so that solution is not saved over the user code
+ if(solution.value === 'Show solution') {
+ userEntry = textarea.value;
+ } else {
+ solutionEntry = textarea.value;
+ }
+
+ updateCode();
+};</pre>
+
+<pre class="brush: css">html {
+ font-family: sans-serif;
+}
+
+h2 {
+ font-size: 16px;
+}
+
+.a11y-label {
+ margin: 0;
+ text-align: right;
+ font-size: 0.7rem;
+ width: 98%;
+}
+
+body {
+ margin: 10px;
+ background-color: #f5f9fa;
+}</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Playable_code', '100%', 730, "", "", "hide-codepen-jsfiddle") }}</p>
+
+<h2 id="Практика_Топ_5_поисовых_запросов">Практика: Топ 5 поисовых запросов</h2>
+
+<p>Хорошим тоном, является использование методов массива, таких как {{jsxref ("Array.prototype.push ()", "push ()")}} и {{jsxref ("Array.prototype.pop ()", "pop ()") }} - это когда вы ведете запись активных элементов в веб-приложении. Например, в анимированной сцене может быть массив объектов, представляющих текущую отображаемую фоновую графику и вам может потребоваться только 50 одновременных отображений по причинам производительности или беспорядка. Когда новые объекты создаются и добавляются в массив, более старые могут быть удалены из массива для поддержания нужного числа.</p>
+
+<p>В этом примере мы собираемся показать гораздо более простое использование - ниже мы даем вам поддельный поисковый сайт с полем поиска. Идея заключается в том, что когда в поле поиска вводятся запросы, в списке отображаются 5 предыдущих поисковых запросов. Когда число терминов превышает 5, последний член начинает удаляться каждый раз, когда новый член добавляется в начало, поэтому всегда отображаются 5 предыдущих терминов.</p>
+
+<div class="note">
+<p><strong>Примечание:</strong> В реальном приложении для поиска вы, вероятно, сможете щелкнуть предыдущие условия поиска, чтобы вернуться к предыдущим поисковым запросам и отобразите фактические результаты поиска! На данный момент мы просто сохраняем его.</p>
+</div>
+
+<p>Чтобы завершить приложение, вам необходимо:</p>
+
+<ol>
+ <li>Добавьте строку под комментарием <code>// number 1</code>, которая добавляет текущее значение, введенное в ввод поиска, к началу массива. Его можно получить с помощью <code>searchInput.value</code>.</li>
+ <li>Добавьте строку под комментарием <code>// number 2</code>, которая удаляет значение, находящееся в конце массива.</li>
+</ol>
+
+<div class="hidden">
+<h6 id="Playable_code_2">Playable code 2</h6>
+
+<pre class="brush: html">&lt;!-- Здесь тоже ничего не выделяйте, не копируйте, не всавляйте!
+  Еле починил --&gt;
+
+&lt;h2&gt;Live output&lt;/h2&gt;
+&lt;div class="output" style="min-height: 150px;"&gt;
+
+&lt;input type="text"&gt;&lt;button&gt;Search&lt;/button&gt;
+
+&lt;ul&gt;
+
+&lt;/ul&gt;
+
+&lt;/div&gt;
+
+&lt;h2&gt;Editable code&lt;/h2&gt;
+
+&lt;p class="a11y-label"&gt;Press Esc to move focus away from the code area (Tab inserts a tab character).&lt;/p&gt;
+
+
+&lt;textarea id="code" class="playable-code" style="height: 370px; width: 95%"&gt;
+var list = document.querySelector('.output ul');
+var searchInput = document.querySelector('.output input');
+var searchBtn = document.querySelector('.output button');
+
+list.innerHTML = '';
+
+var myHistory = [];
+
+searchBtn.onclick = function() {
+ // we will only allow a term to be entered if the search input isn't empty
+ if (searchInput.value !== '') {
+ // number 1
+
+ // empty the list so that we don't display duplicate entries
+ // the display is regenerated every time a search term is entered.
+ list.innerHTML = '';
+
+ // loop through the array, and display all the search terms in the list
+ for (var i = 0; i &lt; myHistory.length; i++) {
+ itemText = myHistory[i];
+ var listItem = document.createElement('li');
+ listItem.textContent = itemText;
+ list.appendChild(listItem);
+ }
+
+ // If the array length is 5 or more, remove the oldest search term
+ if (myHistory.length &gt;= 5) {
+ // number 2
+
+ }
+
+ // empty the search input and focus it, ready for the next term to be entered
+ searchInput.value = '';
+ searchInput.focus();
+ }
+}
+&lt;/textarea&gt;
+
+&lt;div class="playable-buttons"&gt;
+ &lt;input id="reset" type="button" value="Reset"&gt;
+ &lt;input id="solution" type="button" value="Show solution"&gt;
+&lt;/div&gt;</pre>
+
+<pre class="brush: css">html {
+ font-family: sans-serif;
+}
+
+h2 {
+ font-size: 16px;
+}
+
+.a11y-label {
+ margin: 0;
+ text-align: right;
+ font-size: 0.7rem;
+ width: 98%;
+}
+
+body {
+ margin: 10px;
+ background: #f5f9fa;
+}</pre>
+
+<pre class="brush: js">var textarea = document.getElementById('code');
+var reset = document.getElementById('reset');
+var solution = document.getElementById('solution');
+var code = textarea.value;
+var userEntry = textarea.value;
+
+function updateCode() {
+ eval(textarea.value);
+}
+
+reset.addEventListener('click', function() {
+ textarea.value = code;
+ userEntry = textarea.value;
+ solutionEntry = jsSolution;
+ solution.value = 'Show solution';
+ updateCode();
+});
+
+solution.addEventListener('click', function() {
+ if(solution.value === 'Show solution') {
+ textarea.value = solutionEntry;
+ solution.value = 'Hide solution';
+ } else {
+ textarea.value = userEntry;
+ solution.value = 'Show solution';
+ }
+ updateCode();
+});
+
+var jsSolution = 'var list = document.querySelector(\'.output ul\');\nvar searchInput = document.querySelector(\'.output input\');\nvar searchBtn = document.querySelector(\'.output button\');\n\nlist.innerHTML = \'\';\n\nvar myHistory= [];\n\nsearchBtn.onclick = function() {\n if(searchInput.value !== \'\') {\n myHistory.unshift(searchInput.value);\n\n list.innerHTML = \'\';\n\n for(var i = 0; i &lt; myHistory.length; i++) {\n itemText = myHistory[i];\n var listItem = document.createElement(\'li\');\n listItem.textContent = itemText;\n list.appendChild(listItem);\n }\n\n if(myHistory.length &gt;= 5) {\n myHistory.pop();\n }\n\n searchInput.value = \'\';\n searchInput.focus();\n }\n}';
+var solutionEntry = jsSolution;
+
+textarea.addEventListener('input', updateCode);
+window.addEventListener('load', updateCode);
+
+// stop tab key tabbing out of textarea and
+// make it write a tab at the caret position instead
+
+textarea.onkeydown = function(e){
+ if (e.keyCode === 9) {
+ e.preventDefault();
+ insertAtCaret('\t');
+ }
+
+ if (e.keyCode === 27) {
+ textarea.blur();
+ }
+};
+
+function insertAtCaret(text) {
+ var scrollPos = textarea.scrollTop;
+ var caretPos = textarea.selectionStart;
+
+ var front = (textarea.value).substring(0, caretPos);
+ var back = (textarea.value).substring(textarea.selectionEnd, textarea.value.length);
+ textarea.value = front + text + back;
+ caretPos = caretPos + text.length;
+ textarea.selectionStart = caretPos;
+ textarea.selectionEnd = caretPos;
+ textarea.focus();
+ textarea.scrollTop = scrollPos;
+}
+
+// Update the saved userCode every time the user updates the text area code
+
+textarea.onkeyup = function(){
+ // We only want to save the state when the user code is being shown,
+ // not the solution, so that solution is not saved over the user code
+ if(solution.value === 'Show solution') {
+ userEntry = textarea.value;
+ } else {
+ solutionEntry = textarea.value;
+ }
+
+ updateCode();
+};</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Playable_code_2', '100%', 700, "", "", "hide-codepen-jsfiddle") }}</p>
+
+<h2 id="Заключение">Заключение</h2>
+
+<p>Прочитав эту статью, мы уверены, что вы согласитесь, что массивы кажутся довольно полезными; вы увидите, что они появляются повсюду в JavaScript, часто в сочетании с циклами, чтобы делать то же самое для каждого элемента массива. Мы научим вас всем полезным основам, которые нужно знать о циклах в следующем модуле, но пока вы должны себе похлопать и воспользоваться заслуженным перерывом; вы проработали все статьи в этом модуле!</p>
+
+<p>Осталось только выполнить тестовую задачу, которая проверит ваше понимание статей, которые Вы прочли до этого момента. Удачи!</p>
+
+<h2 id="Посмотрите_также">Посмотрите также</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Web/JavaScript/Guide/Indexed_collections">Indexed collections</a> — an advanced level guide to arrays and their cousins, typed arrays.</li>
+ <li>{{jsxref("Array")}} — the <code>Array</code> object reference page — for a detailed reference guide to the features discussed in this page, and many more.</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/Useful_string_methods", "Learn/JavaScript/Первые_шаги/Создатель_глуых_историй", "Learn/JavaScript/Первые_шаги")}}</p>
+
+<h2 id="В_этом_разделе">В этом разделе</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/What_is_JavaScript">Что такое JavaScript?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/A_first_splash">A first splash into JavaScript</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/What_went_wrong">What went wrong? Troubleshooting JavaScript</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Variables">Storing the information you need — Variables</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Math">Basic math in JavaScript — numbers and operators</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Strings">Handling text — strings in JavaScript</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Useful_string_methods">Useful string methods</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Arrays">Массивы</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Silly_story_generator">Assessment: Silly story generator</a></li>
+</ul>
diff --git a/files/ru/learn/javascript/первые_шаги/index.html b/files/ru/learn/javascript/первые_шаги/index.html
new file mode 100644
index 0000000000..bd435e920f
--- /dev/null
+++ b/files/ru/learn/javascript/первые_шаги/index.html
@@ -0,0 +1,56 @@
+---
+title: Первые шаги в JavaScript
+slug: Learn/JavaScript/Первые_шаги
+tags:
+ - JavaScript
+ - Массивы
+ - Новичкам
+translation_of: Learn/JavaScript/First_steps
+---
+<div>{{LearnSidebar}}</div>
+
+<p class="summary">В нашем первом модуле, прежде чем перейти к практике написания кода на языке JavaScript, сначала мы дадим ответы на некоторые фундаментальные вопросы, а именно: "Что же такое JavaScript?", "Что он из себя представляет?" и "Что он может делать?". После этого мы внимательно рассмотрим некоторые из ключевых элементов, такие как переменные, строки, числа и массивы.</p>
+
+<h2 id="Предисловие">Предисловие</h2>
+
+<p>Вам не нужно иметь никаких предварительных знаний JavaScript чтобы приступить к этому модулю, но у вас должно быть некоторое представление о HTML и CSS. Рекомендуем ознакомиться со следующими материалами, прежде чем начинать знакомство с JavaScript:</p>
+
+<ul>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/Getting_started_with_the_web">Начало работы с Web</a>  (которое включает в себя общее <a href="/ru/docs/Learn/Getting_started_with_the_web/JavaScript_basics">введение в Javascript</a>)</li>
+ <li><a href="/ru/docs/Learn/HTML/%D0%92%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B2_HTML">Введение в HTML</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/CSS/Introduction_to_CSS">Введение в CSS</a></li>
+</ul>
+
+<div class="note">
+<p><span style="font-size: 14px;"><strong>Примечание:</strong></span>  Если Вы работаете на компьютере, планшете или другом устройстве, где нет возможности полноценно работать с файлами, можете использовать такие онлайн сервисы как  <a href="http://jsbin.com/">JSBin</a> или <a href="https://thimble.mozilla.org/">Thimble</a>, для запуска примеров кода. </p>
+</div>
+
+<h2 id="Руководства">Руководства</h2>
+
+<dl>
+ <dt><a href="/ru/docs/Learn/JavaScript/%D0%9F%D0%B5%D1%80%D0%B2%D1%8B%D0%B5_%D1%88%D0%B0%D0%B3%D0%B8/What_is_JavaScript">Что такое JavaScript?</a></dt>
+ <dd>Добро пожаловать на курс начинающего JavaScript разработчика от MDN! В первой статье мы рассмотрим JavaScript в общем приближении и постараемся ответить на вопросы "Что такое JavaScript?" и "Для чего он предназначен?", и закрепим верное понимание его назначения. </dd>
+ <dt><a href="/ru/docs/Learn/JavaScript/%D0%9F%D0%B5%D1%80%D0%B2%D1%8B%D0%B5_%D1%88%D0%B0%D0%B3%D0%B8/A_first_splash">Первое погружение в JavaScript</a></dt>
+ <dd>Теперь, когда вы знаете кое-что о JavaScript, и что он может делать, мы предлагаем вам пройти интенсивный практический урок по базовой функциональности JavaScript. Здесь вы, шаг за шагом, создадите простую игру "Угадай число".</dd>
+ <dt><a href="/ru/docs/Learn/JavaScript/%D0%9F%D0%B5%D1%80%D0%B2%D1%8B%D0%B5_%D1%88%D0%B0%D0%B3%D0%B8/%D0%A7%D1%82%D0%BE_%D0%BF%D0%BE%D1%88%D0%BB%D0%BE_%D0%BD%D0%B5_%D1%82%D0%B0%D0%BA">Что пошло не так? Устранение ошибок JavaScript</a></dt>
+ <dd>В процессе создания игры "Угадай число" из предыдущего урока, вы могли заметить что она не работала. Не стоит унывать - данная статья научит вас беречь собственные нервы, а так же, даст несколько советов о том как решать такие проблемы, искать и исправлять неполадки в JavaScript коде.</dd>
+ <dt><a href="/ru/docs/Learn/JavaScript/%D0%9F%D0%B5%D1%80%D0%B2%D1%8B%D0%B5_%D1%88%D0%B0%D0%B3%D0%B8/Variables">Хранение нужной вам информации - Переменные</a></dt>
+ <dd>После прочтения предыдущих статей вы должны знать что из себя представляет JavaScript, что он может, как взаимодействует с другими web технологиями, и каковы его основные особенности в общем приближении. В этой статье спустимся к самым основам языка и поработаем с <strong>Переменными</strong>.</dd>
+ <dt><a href="/ru/docs/Learn/JavaScript/%D0%9F%D0%B5%D1%80%D0%B2%D1%8B%D0%B5_%D1%88%D0%B0%D0%B3%D0%B8/Math">Базовая математика в JavaScript — числа и операторы</a></dt>
+ <dd>Здесь мы обсуждаем математику в JavaScript - каким образом мы можем манипулировать числами и операторами для работы с ними.</dd>
+ <dt><a href="/ru/docs/Learn/JavaScript/%D0%9F%D0%B5%D1%80%D0%B2%D1%8B%D0%B5_%D1%88%D0%B0%D0%B3%D0%B8/%D0%A1%D1%82%D1%80%D0%BE%D0%BA%D0%B8">Работа с текстом — строки в JavaScript</a></dt>
+ <dd>Теперь мы обратим своё внимание на строки - так называются кусочки текста в программировании. В этой статье мы рассмотрим то что действительно необходимо знать про строки в JavaScript: как создать строку, делать escape (экранирование) символов с помощью кавычек, и объединять их.</dd>
+ <dt><a href="/ru/docs/Learn/JavaScript/%D0%9F%D0%B5%D1%80%D0%B2%D1%8B%D0%B5_%D1%88%D0%B0%D0%B3%D0%B8/Useful_string_methods">Полезные строковые методы</a></dt>
+ <dd>После того как мы рассмотрели основы работы со строками, давайте двинемся дальше и поговорим о том какие полезные операторы и методы существуют для строк, такие как вычисление длины, соединение и разделение строк, замена отдельных символов и многие другие. </dd>
+ <dt><a href="/ru/docs/Learn/JavaScript/%D0%9F%D0%B5%D1%80%D0%B2%D1%8B%D0%B5_%D1%88%D0%B0%D0%B3%D0%B8/Arrays">Массивы</a></dt>
+ <dd>В последней статье этого модуля мы рассмотрим массивы - изящный способ хранения различных наборов информации в имени всего одной переменной. Здесь мы поговорим о том почему это может быть полезным, рассмотрим как создать массив, получить, добавить или удалить элемент массива, и прочее.</dd>
+</dl>
+
+<h2 id="Проверка_полученных_знаний">Проверка полученных знаний</h2>
+
+<p>Предложенное тестовое задание проверит ваше понимание основ JavaScript, которые вы получили пройдя предложенные выше уроки. </p>
+
+<dl>
+ <dt><a href="/ru/docs/Learn/JavaScript/%D0%9F%D0%B5%D1%80%D0%B2%D1%8B%D0%B5_%D1%88%D0%B0%D0%B3%D0%B8/%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D1%82%D0%B5%D0%BB%D1%8C_%D0%B3%D0%BB%D1%83%D1%8B%D1%85_%D0%B8%D1%81%D1%82%D0%BE%D1%80%D0%B8%D0%B9">Генератор глупых историй</a></dt>
+ <dd>Вашим заданием будет применить на практике полученные знания и создать развлекательное приложение которое будет генерировать случайные нелепые истории.</dd>
+</dl>
diff --git a/files/ru/learn/javascript/первые_шаги/math/index.html b/files/ru/learn/javascript/первые_шаги/math/index.html
new file mode 100644
index 0000000000..29ff9258bf
--- /dev/null
+++ b/files/ru/learn/javascript/первые_шаги/math/index.html
@@ -0,0 +1,423 @@
+---
+title: Базовая математика в JavaScript — числа и операторы
+slug: Learn/JavaScript/Первые_шаги/Math
+tags:
+ - JavaScript
+ - Гайд
+ - Математика
+ - Начинающий
+ - Операторы
+ - Руководство
+ - Скриптинг
+ - Статья
+ - кодинг
+translation_of: Learn/JavaScript/First_steps/Math
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/Variables", "Learn/JavaScript/Первые_шаги/Строки", "Learn/JavaScript/Первые_шаги")}}</div>
+
+<p class="summary">В этой части курса мы обсуждаем математику в JavaScript — как мы можем использовать {{Glossary("Operator","operators")}} и другие функции, чтобы успешно манипулировать числами для выполнения наших задач.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Необходимые условия:</th>
+ <td>Базовая компьютерная грамотность, базовое понимание HTML и CSS, понимание того, что такое JavaScript.</td>
+ </tr>
+ <tr>
+ <th scope="row">Цель:</th>
+ <td>Ознакомление с основами математики в JavaScript.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Все_любят_математику">Все любят математику</h2>
+
+<p>Хорошо, может быть, не все. Некоторые из нас любят математику, некоторые из нас ненавидели математику с тех пор, как мы изучали таблицу умножения в школе, а некоторые из нас находятся где-то между ними. Но никто из нас не может отрицать, что математика является фундаментальной частью жизни, и мы не можем обойтись без нее. Это особенно актуально, когда мы учимся программировать на JavaScript (или на любом другом языке, если на то пошло) — большая часть того, что мы делаем, опирается на обработку числовых данных, вычисление новых значений и т.д. Так что не удивительно, что JavaScript имеет полнофункциональный набор математических функций.</p>
+
+<p>В этой статье обсуждаются только основные разделы, которые вам нужно знать сейчас.</p>
+
+<h3 id="Типы_чисел">Типы чисел</h3>
+
+<p>В программировании даже скромная система десятичных чисел, которую мы все так хорошо знаем, сложнее, чем вы думаете. Мы используем разные термины для описания различных типов десятичных чисел. Например:</p>
+
+<ul>
+ <li><strong>Целые </strong>— это целые числа, такие как: 10, 400, или -5.</li>
+ <li><strong>С плавающей точкой </strong><em>(или: с плавающей запятой) </em>— имеют целую и дробную части, например: 12.5 или 56.7786543.</li>
+ <li><strong>Doubles </strong>— тип чисел с плавающей точкой, которые имеют большую точность, чем стандартные числа с плавающей точкой (что означает, что они точны для большего числа десятичных знаков).</li>
+</ul>
+
+<p>У нас даже есть разные типы числовых систем:</p>
+
+<ul>
+ <li><strong>Бинарная</strong> — низкоуровневый язык компьютеров; нули и единицы (0 и 1);</li>
+ <li><strong>Восьмеричная</strong> — 8-ми разрядная, использует 0–7 в каждом столбце;</li>
+ <li><strong>Десятичная</strong> — 10-ти разрядная, использует 0-9 в каждом столбце;</li>
+ <li><strong>Шестнадцатеричная</strong> — 16-ти разрядная, используюет 0–9 и потом a–f в каждом столбце. Вы, возможно, уже встречали эти числа, когда задавали <a href="/en-US/Learn/CSS/Introduction_to_CSS/Values_and_units#Hexadecimal_values">цвет в CSS</a>.</li>
+</ul>
+
+<p><strong>Прежде чем взорвется ваш мозг, остановитесь прямо здесь и сейчас!</strong> </p>
+
+<p>Во-первых, мы просто будем придерживаться десятичных чисел на протяжении всего курса; вы редко когда будете сталкиваться с необходимостью думать в других числовых системах, если вообще когда-либо с ней сталкнетесь.</p>
+
+<p>Во-вторых, в отличие от некоторых других языков программирования, JavaScript имеет только один тип данных для чисел, как вы догадались это {{jsxref("Number")}}. Это означает, независимо от типа чисел, с которыми вы работаете в JavaScript, обрабатывать вы их будете точно так же.</p>
+
+<h3 id="Для_меня_всё_—_числа">Для меня всё — числа</h3>
+
+<p>Давайте быстро поиграем с некоторыми числами, чтобы снова познакомиться с основным синтаксисом, который нам нужен. Введите команды, перечисленные ниже, в вашу консоль (<a href="/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools">developer tools JavaScript console</a>), или используйте простую встроенную консоль.</p>
+
+<ol>
+ <li>Прежде всего, давайте объявим пару переменных и инициализируем их целым числом и числом с плавающей точкой, соответственно, затем введите имена переменных обратно, чтобы проверить, что все в порядке:
+ <pre class="brush: js">var myInt = 5;
+var myFloat = 6.667;
+myInt;
+myFloat;</pre>
+ </li>
+ <li>Числовые значения набираются без кавычек. Попробуйте объявить и инициализировать еще пару переменных, содержащих числа, прежде чем двигаться дальше.</li>
+ <li>Теперь давайте убедимся, что обе переменные содержат одинаковый тип данных. Для этого есть оператор {{jsxref("Operators/typeof", "typeof")}}, который позволяет проверить какой тип данных содержит в себе переменная. Введите две приведенные ниже строки:
+ <pre class="brush: js">typeof myInt;
+typeof myFloat;</pre>
+ В обоих случаях вы должны получить <code>"number"</code> — это все упрощает, чем если бы разные числа имели разные типы данных, и нам приходилось иметь дело с ними по-разному.</li>
+</ol>
+
+<h2 id="Арифметические_операторы">Арифметические операторы</h2>
+
+<p dir="ltr" id="tw-target-text">Арифметические операторы — это основные операторы, которые мы используем для различных математических операций, например таких, как сложение или вычитание:</p>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">Оператор</th>
+ <th scope="col">Имя</th>
+ <th scope="col">Функция</th>
+ <th scope="col">Пример</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><code>+</code></td>
+ <td>Сложение</td>
+ <td>Объединение чисел в одно целое.</td>
+ <td><code>6 + 9</code></td>
+ </tr>
+ <tr>
+ <td><code>-</code></td>
+ <td>Вычитание</td>
+ <td>Вычитает правое число от левого.</td>
+ <td><code>20 - 15</code></td>
+ </tr>
+ <tr>
+ <td><code>*</code></td>
+ <td>Умножение</td>
+ <td>Умножает два числа вместе.</td>
+ <td><code>3 * 7</code></td>
+ </tr>
+ <tr>
+ <td><code>/</code></td>
+ <td>Деление</td>
+ <td>Делит левое число на правое.</td>
+ <td><code>10 / 5</code></td>
+ </tr>
+ <tr>
+ <td><code>%</code></td>
+ <td>Модуль числа</td>
+ <td>
+ <p>Возвращает значение остатка при делении первого числа на второе. Результат будет иметь тот же знак, что и первое число.</p>
+ </td>
+ <td>
+ <p><code>11 % 3 = 2</code> (поскольку число 3 вмещается три раза, остатком будет число 2)</p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>**</code></td>
+ <td>показатель степени</td>
+ <td>Возводит базовое число в указанную степень, то есть количество базовых чисел, указанных экспонентой, умножается вместе. Впервые он был представлен в EcmaScript 2016.</td>
+ <td><code>5 ** 5</code> (возвращает 3125, или как: 5*5*5*5*5)</td>
+ </tr>
+ </tbody>
+</table>
+
+<div class="note">
+<p><strong>Примечание</strong>: Иногда числа участвующие в математических операциях называют операндами ( {{Glossary("Operand", "operands")}} ).</p>
+</div>
+
+<p dir="ltr" id="tw-target-text">Нам, вероятно, не нужно учить вас базовым математическим операциям, но мы хотели бы проверить ваше понимание синтаксиса. Попробуйте ввести приведенные ниже примеры в свою консоль (<a href="/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools">developer tools JavaScript console</a>), или используйте встроенную консоль, с которой вы уже знакомы, чтобы ознакомиться с синтаксисом.</p>
+
+<ol>
+ <li>Для начала попробуйте ввести простые примеры, такие как:
+ <pre class="brush: js">10 + 7
+9 * 8
+60 % 3</pre>
+ </li>
+ <li>Вы также можете попробовать объявить переменные и присвоить им различные числа. Попробуйте вместо чисел использовать ранее объявленные переменные — переменные будут вести себя точно так же, как значения, которые они хранят. Например:
+ <pre class="brush: js">var num1 = 10;
+var num2 = 50;
+9 * num1;
+num2 / num1;</pre>
+ </li>
+ <li>И напоследок, попробуйте ввести более сложные выражения, например:
+ <pre class="brush: js">5 + 10 * 3;
+num2 % 9 * num1;
+num2 + num1 / 8 + 2;</pre>
+ </li>
+</ol>
+
+<p>Некоторые примеры выше могут дать вам не тот результат, которого вы ожидали; приведенный ниже раздел может дать ответ на вопрос о том, почему.</p>
+
+<h3 id="Приоритет_операторов">Приоритет операторов</h3>
+
+<p>Давайте взглянем на последний пример сверху. Предположим, что <code>num2</code> содержит значение 50 и <code>num1</code> содержит значение 10 (как и было обозначено выше):</p>
+
+<pre class="brush: js">num2 + num1 / 8 + 2;</pre>
+
+<p>Будучи человеком, вы, вероятно, прочитаете это как <em>"50 плюс 10 равно 60",</em> затем <em>"8 плюс 2 равно 10"</em>, и, наконец, <em>"60 делить на 10 равно 6"</em>.</p>
+
+<p>Но браузер видит это по-другому: <em>"10 делить на 8 равно 1.25", </em>затем <em>"50 плюс 1.25 плюс 2 равно 53.25".</em></p>
+
+<p>Это происходит из-за <strong>приоритета операторов</strong> - некоторые операторы будут применены перед другими в процесс вычисления суммы (в программировании ее называют выражением). Приоритет операторов в JavaScript ничем не отличается от приоритета арифметических операций, который вы изучали в школе - умножение и деление всегда выполняются первыми, затем сложение и вычитание (сумма всегда вычисляется слева направо).</p>
+
+<p>Если вы хотите переопределить порядок выполнения операторов, вы можете окружить парными скобками часть выражения, которая должна быть выполнена первой. Для получения результата 6 вам следует сделать следующее:</p>
+
+<pre class="brush: js">(num2 + num1) / (8 + 2);</pre>
+
+<p>Результат этого выражения равен 6.</p>
+
+<div class="note">
+<p><strong>Заметка</strong>: полный список операторов JavaScript и приоритетов их выполнения можно найти по этой ссылке: <a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Operator_precedence">Expressions and operators</a>.</p>
+</div>
+
+<h2 id="Операторы_инкремента_и_декремента">Операторы инкремента и декремента</h2>
+
+<p>Иногда вам захочется повторно добавить или вычесть единцу к/из значению числовой переменной. Это можно сделать с помощью оператора инкремента (<code>++</code>) и декремента (<code>--</code>). Мы использовали <code>++</code> в нашей игре "Угадай число" в статье <a href="/ru/docs/Learn/JavaScript/%D0%9F%D0%B5%D1%80%D0%B2%D1%8B%D0%B5_%D1%88%D0%B0%D0%B3%D0%B8/A_first_splash">первое погружение в JavaScript</a>, где мы добавляли 1 к переменной <code>guessCount</code>, в которой хранилось значение количества попыток пользователя после каждого хода.</p>
+
+<pre class="brush: js">guessCount++;</pre>
+
+<div class="note">
+<p><strong>Замечание</strong>: инкремент и декремент часто используются в <a href="/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration">циклах</a>, о которых вы узнаете позже. Например, если вы захотите пройтись по списку цен и добавить к каждой налог с продаж, вам придется в цикле обойти каждую цену и провести необходимые вычисления для учета налога. Инкремент будет использован для перехода на новую ячейку списка при необходимости. У нас есть несложный пример реализации такого списка - попробуйте и взгляните на код чтобы посмотреть, сможете ли вы найти инкременты! Мы взглянем на циклы поближе позже по ходу курса.</p>
+</div>
+
+<p>Давайте попробуем сыграть с этим в вашей консоли. Для начала заметим, что вы не можете использовать инкремент/декремент непосредсвенно к числу, что может показаться странным. Дело в том, что мы присваиваем к переменной новое обновленное число, а не просто вычисляем значение. Следующий пример приведет к ошибке:</p>
+
+<pre class="brush: js">3++;</pre>
+
+<p>Таким образом, вы можете применить инкремент только к существующим переменным:</p>
+
+<pre class="brush: js">var num1 = 4;
+num1++;</pre>
+
+<p>Так, вторая странность! Если вы сделаете это, вы получите значение 4 - бразуер возвращает текущее число, после чего применяет к нему оператор инкремента. Вы можете удостовериться в том, что инкремент был применен, узнав значение переменной еще раз:</p>
+
+<pre class="brush: js">num1;</pre>
+
+<p>То же самое для <code>--</code>: попробуйте пример ниже</p>
+
+<pre class="brush: js">var num2 = 6;
+num2--;
+num2;</pre>
+
+<div class="note">
+<p><strong>Замечание</strong>: вы можете заставить делать это в другом порядке - применить инкремент/декремент и только потом вернуть значение. Для этого необходимо записать оператор слева от переменной, а не справа. Попробуйте пример сверху еще раз, но в этот раз используйте <code>++num1</code> и <code>--num2</code>. </p>
+</div>
+
+<h2 id="Операторы_присваивания">Операторы присваивания</h2>
+
+<p>Операторы присваивания - операторы, которые присваивают значение переменным. Мы уже много раз использовали самый простой из них, <code>=</code>, он просто приравнивает значение переменной слева к значению справа:</p>
+
+<pre class="brush: js">var x = 3; // x содержит значение 3
+var y = 4; // y содержит значение 4
+x = y; // x теперь содержит значение y (x == 4)</pre>
+
+<p>Однако есть еще несколько сложных конструкций, которые позволяют делать ваш код более простым и аккуратным. Наиболее часто используемые перечислены ниже:</p>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">Operator</th>
+ <th scope="col">Name</th>
+ <th scope="col">Purpose</th>
+ <th scope="col">Example</th>
+ <th scope="col">Shortcut for</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><code>+=</code></td>
+ <td>Присваивание сложения</td>
+ <td>Прибавляет значение справа к переменной слева и возвращает новое значение переменной</td>
+ <td><code>x = 3;<br>
+ x += 4;</code></td>
+ <td><code>x = 3;<br>
+ x = x + 4;</code></td>
+ </tr>
+ <tr>
+ <td><code>-=</code></td>
+ <td>Присваивание вычитания</td>
+ <td>Вычитает значение справа из переменной слева и возвращает новое зачение переменной</td>
+ <td><code>x = 6;<br>
+ x -= 3;</code></td>
+ <td><code>x = 6;<br>
+ x = x - 3;</code></td>
+ </tr>
+ <tr>
+ <td><code>*=</code></td>
+ <td>
+ <p>Присваивание умножения</p>
+ </td>
+ <td>Умножает переменную слева на значение справа и возвращает новое зачение переменной</td>
+ <td><code>x = 2;<br>
+ x *= 3;</code></td>
+ <td><code>x = 2;<br>
+ x = x * 3;</code></td>
+ </tr>
+ <tr>
+ <td><code>/=</code></td>
+ <td>Присваивание деления</td>
+ <td>Делит переменную слева на значение справа и возвращает новое зачение переменной</td>
+ <td><code>x = 10;<br>
+ x /= 5;</code></td>
+ <td><code>x = 10;<br>
+ x = x / 5;</code></td>
+ </tr>
+ </tbody>
+</table>
+
+<p>Попробуйте использовать такие конструкции, что понять, как они работают. Сможете ли вы определить значение до того, как напишите вторую строку?</p>
+
+<p>Замьтете, что значение справа может быть как числом (константой), так и переменной, например:</p>
+
+<pre class="brush: js">var x = 3; // x содержит значение 3
+var y = 4; // y содержит значение 4
+x *= y; // x содержит значение 12</pre>
+
+<div class="note">
+<p><strong>Заметка: есть еще <a href="https://developer.mozilla.org/ru/docs/Web/JavaScript/Guide/Expressions_and_Operators">другие операторы присваивания</a></strong>,<strong> в этой статье перечислены только самые базовые.</strong></p>
+</div>
+
+<h2 id="Активное_обучение_меняем_размеры_коробки">Активное обучение: меняем размеры коробки</h2>
+
+<p>В этом упражнении вы будете пользоваться числами и операторами для работы с размерами коробки. Коробка рисуется с помощью API браузера, которое назывется Canvas API. Вам не следует беспокоиться о том, как это работает - просто сосредоточьтесь на математике. Ширина и высота коробки (в пикселях) определяются переменными <code>x</code> и <code>y</code>, которые изначально равны 50.</p>
+
+<p>{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/maths/editable_canvas.html", '100%', 520)}}</p>
+
+<p><strong><a href="https://mdn.github.io/learning-area/javascript/introduction-to-js-1/maths/editable_canvas.html">Открыть в новом окне</a></strong></p>
+
+<p>В коде сверху, который вы можете изменять, под комментарием есть две строчки, с помощью которых вы можете увеличивать/уменьшать размеры коробки. Мы хотим, чтобы вы выполнили несколько заданий:</p>
+
+<ul>
+ <li>Поменяйте строчку с размером x так, чтобы коробка была шириной 50px, причем 50 должно быть вычислено с помощью чисел 43 и 7 и арифмитического оператора.</li>
+ <li>Поменяйте строчку с размером y так, чтобы коробка была высотой 75px, причем 75 должно быть вычислено с помощью чисел 25 и 3 и арифметического оператора.</li>
+ <li>Поменяйте строчку с размером y так, чтобы коробка была высотой 250, при этом 250 вычислено с помощью двух чисел и оператором взятия остатка (модуль).</li>
+ <li>Поменяйте строчку с размером y так, чтобы коробка была высотой 150px, причем 150 вычилено с помощью трех чисел и операторов вычитания и деления.</li>
+ <li>Поменяйте строчку с размером x так, чтобы коробка была шириной 200px, при этом 200 вычислено с помощью числа 4 и оператора присваивания.</li>
+ <li>Поменяйте строчку с размером y так, чтобы коробка была высотой 200px, причем 200 вычислено с помощью чисел 50 и 3 и операторов умножения и присваивания сложения.</li>
+</ul>
+
+<p>Не расстраивайтесть, если вы не поняли код сверху. Нажмите кнопку <em>Reset</em> для запуска программы снова. Если вы смогли ответить верно на все вопросы, попробуйте поэкспериментировать с кодом еще (или, например, предложить друзьям несколько заданий).</p>
+
+<h2 id="Операторы_сравнения">Операторы сравнения</h2>
+
+<p>Иногда нам может понадобиться проверить какое-либо условие, а затем поступить в зависимости от результата - для этого мы используем <strong>операторы сравнения</strong>.</p>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">Оператор</th>
+ <th scope="col">Имя</th>
+ <th scope="col">Назначение</th>
+ <th scope="col">Пример</th>
+ </tr>
+ <tr>
+ <td><code>===</code></td>
+ <td>Строгое равенство</td>
+ <td>Проверяет левое и правое значения на идентичность</td>
+ <td><code>5 === 2 + 4</code></td>
+ </tr>
+ <tr>
+ <td><code>!==</code></td>
+ <td>Строгое неравенство</td>
+ <td>Проверяет левое и правое значения на <strong>не</strong>идентичность</td>
+ <td><code>5 !== 2 + 3</code></td>
+ </tr>
+ <tr>
+ <td><code>&lt;</code></td>
+ <td>Меньше</td>
+ <td>Проверяет, меньше ли левое значение правого</td>
+ <td><code>10 &lt; 6</code></td>
+ </tr>
+ <tr>
+ <td><code>&gt;</code></td>
+ <td>Больше</td>
+ <td>Проверяет, больше ли левое значение правого</td>
+ <td><code>10 &gt; 20</code></td>
+ </tr>
+ <tr>
+ <td>&lt;=</td>
+ <td>Меньше или равно</td>
+ <td>Проверят, меньше ли левое значение правому (или равно ему)</td>
+ <td><code>3 &lt;= 2</code></td>
+ </tr>
+ <tr>
+ <td>&gt;=</td>
+ <td>Больше или равно</td>
+ <td>Проверят, больше ли левое значение левого (или равно ему)</td>
+ <td><code>5 &gt;= 4</code></td>
+ </tr>
+ </thead>
+</table>
+
+<div class="note">
+<p><strong>Заметка</strong>: вы можете заметить, что некоторые люди используют <code>==</code> и <code>!=</code> в их программах для сравнения на равенство и неравенство — это валидные JavaScript-операторы, но они отличаются от <code>===</code>/<code>!==</code> — первая пара проверяет на равенство/неравенство значений, не рассматривая их типы. Вторая пара - строгая версия первой, которая проверяет типы операндов. При использовании строгой версии выявляется больше ошибок, поэтому мы рекомендуем использовать именно ее.</p>
+</div>
+
+<p>Если вы попробуете использовать эти операторы в консоли, вы увидите, что все они возвращают значения <code>true</code>/<code>false</code> — о типе данных <code>boolean</code> мы писали в прошлой статье. С их помощью мы можем принимать решения в нашей программе, например:</p>
+
+<ul>
+ <li>Порождать текст на кнопке в зависимости от того, нажата она или нет.</li>
+ <li>Высвечивать сообщение о поражении при проигрыше или поздравление при победе в игре.</li>
+ <li>Показывать пользователю верное окно приветствия в зависимости от времени года.</li>
+ <li>Увеличивать или уменьшать карту при выборе одной из двух опций.</li>
+</ul>
+
+<p>Мы взглянем на то, как реализовать такую логику после знакомства с условными выражениями в следующей статье. Сейчас мы рассмотрим небольшой пример:</p>
+
+<pre class="brush: html">&lt;button&gt;Запустить машину&lt;/button&gt;
+&lt;p&gt;Машина остановлена&lt;/p&gt;
+</pre>
+
+<pre class="brush: js">var btn = document.querySelector('button');
+var txt = document.querySelector('p');
+
+btn.addEventListener('click', updateBtn);
+
+function updateBtn() {
+ if (btn.textContent === 'Start machine') {
+ btn.textContent = 'Stop machine';
+ txt.textContent = 'The machine has started!';
+ } else {
+ btn.textContent = 'Start machine';
+ txt.textContent = 'The machine id stopped.';
+ }
+}</pre>
+
+<p>{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/maths/conditional.html", '100%', 100)}}</p>
+
+<p><strong><a href="https://mdn.github.io/learning-area/javascript/introduction-to-js-1/maths/conditional.html">Открыть в новом окне</a></strong></p>
+
+<p>Мы использовали оператор равенства внутри функции <code>updateBtn()</code>. В этом случае мы не проверяем пару математических выражений на равенcтво значений — мы просто смотрим, является ли текст на кнопке определенной строкой — что по сути является тем же самым. Если кнопка при нажатии содержит "Start machine", мы меняем содержимое метки на "Stop machine" и обновляем метку. Если же текст кнопки — "Stop machine", при нажатии мы возвращем все обратно. </p>
+
+<div class="note">
+<p><strong>Заметка</strong>: Такой элемент управления, который переключается между двумя состояниями, обычно называется <strong>тумблером</strong>. Он переключается между одним состоянием и другим: свет включен, свет выключен и т. д.</p>
+</div>
+
+<h2 id="Итого">Итого</h2>
+
+<p>В этой статье мы привели основную информацию, необходимую для работы с числами в JavaScript. Вы постоянно будете использовать числа в процессе обучения языку, поэтому желательно разобраться в этом сейчас. Если вам действительно не нравится математика, пусть вас утешит, что эта статья была сравнительно короткой.</p>
+
+<p>В следующей статье мы изучим текст и то, как мы работаем с ним в JavaScript.</p>
+
+<div class="note">
+<p><strong>Примечание</strong>: если вам хочется узнать подробнее о том, как математика реализуется в JavaScript, вы можете посмотерть главный раздел JavaScript MDN. Статьи <a href="/ru/docs/Web/JavaScript/Guide/Numbers_and_dates">Числа и даты</a> и <a href="/ru/docs/Web/JavaScript/Reference/Operators">Выражения и операторы</a> - хороший вариант для начала.</p>
+</div>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/Variables", "Learn/JavaScript/Первые_шаги/Строки", "Learn/JavaScript/Первые_шаги")}}</p>
diff --git a/files/ru/learn/javascript/первые_шаги/useful_string_methods/index.html b/files/ru/learn/javascript/первые_шаги/useful_string_methods/index.html
new file mode 100644
index 0000000000..1318ee39ac
--- /dev/null
+++ b/files/ru/learn/javascript/первые_шаги/useful_string_methods/index.html
@@ -0,0 +1,723 @@
+---
+title: Полезные строковые методы
+slug: Learn/JavaScript/Первые_шаги/Useful_string_methods
+tags:
+ - Beginner
+ - CodingScripting
+ - JavaScript
+ - Learn
+ - length
+ - lower
+ - replace
+ - split
+ - upper
+ - Обучение
+ - Регистр
+translation_of: Learn/JavaScript/First_steps/Useful_string_methods
+---
+<p>{{LearnSidebar}}</p>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/Строки", "Learn/JavaScript/Первые_шаги/Arrays", "Learn/JavaScript/Первые_шаги")}}</p>
+
+<p>Мы рассмотрели базовые понятия, касающиеся строк. Давайте пойдем дальше и рассмотрим, какие полезные операции мы можем выполнять со строками, используя встроенные функции, такие как поиск длины текстовой строки, объединение и разделение строк, замена одного символа из строки другим и многое другое.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row" style="background-color: rgb(255, 232, 212);"><strong>Необходимые знания:</strong></th>
+ <td style="background-color: rgb(255, 232, 212);">Базовая компьютерная грамотность, базовое понимание HTML и CSS, понимание того, что такое JavaScript.</td>
+ </tr>
+ <tr>
+ <th scope="row" style="background-color: rgb(255, 232, 212);"><strong>Задача:</strong></th>
+ <td style="background-color: rgb(255, 232, 212);">Понять, что строки являются объектами, и изучить, как использовать некоторые из основных методов, доступных для этих объектов для управления строками.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Строки_как_объекты">Строки как объекты</h2>
+
+<p id="Useful_string_methods">Почти всё в JavaScript является объектами. Когда вы создаете строку, например: </p>
+
+<pre class="notranslate">let string = 'This is my string';</pre>
+
+<p>ваша переменная становится строковым объектом, и, как результат, ей доступно множество свойств и методов. Можете убедиться в этом, перейдя на страницу {{jsxref ("String")}} и просмотрев на ней список свойств и методов!</p>
+
+<p><strong>Только не волнуйтесь!</strong> Большинство из них вам не нужно знать сейчас на ранней стадии вашего обучения. Но некоторые из них вы, возможно, будете использовать довольно часто. Их мы и рассмотрим.</p>
+
+<p>Приведем несколько примеров в новой консоли. Ниже вы можете <a href="https://mdn.github.io/learning-area/javascript/introduction-to-js-1/variables/index.html">открыть данную консоль</a> в отдельной вкладке или окне, или, если вам так удобней, использовать <a href="https://developer.mozilla.org/ru/docs/Learn/Discover_browser_developer_tools">браузер консоли разработчика</a>.</p>
+
+<div class="hidden">
+<h6 id="Hidden_code">Hidden code</h6>
+
+<pre class="brush: html line-numbers language-html notranslate"><code class="language-html">&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+ &lt;head&gt;
+ &lt;meta charset="utf-8"&gt;
+ &lt;title&gt;Консоль JavaScript&lt;/title&gt;
+ &lt;style&gt;
+ * {
+ box-sizing: border-box;
+ }
+
+ html {
+ background-color: #0C323D;
+ color: #809089;
+ font-family: monospace;
+ }
+
+ body {
+ max-width: 700px;
+ }
+
+ p {
+ margin: 0;
+ width: 1%;
+ padding: 0 1%;
+ font-size: 16px;
+ line-height: 1.5;
+ float: left;
+ }
+
+ .input p {
+ margin-right: 1%;
+ }
+
+ .output p {
+ width: 100%;
+ }
+
+ .input input {
+ width: 96%;
+ float: left;
+ border: none;
+ font-size: 16px;
+ line-height: 1.5;
+ font-family: monospace;
+ padding: 0;
+ background: #0C323D;
+ color: #809089;
+ }
+
+ div {
+ clear: both;
+ }
+
+ &lt;/style&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+
+
+ &lt;/body&gt;
+
+ &lt;script&gt;
+ var geval = eval;
+ function createInput() {
+ var inputDiv = document.createElement('div');
+ var inputPara = document.createElement('p');
+ var inputForm = document.createElement('input');
+
+ inputDiv.setAttribute('class', 'input');
+ inputPara.textContent = '&gt;';
+ inputDiv.appendChild(inputPara);
+ inputDiv.appendChild(inputForm);
+ document.body.appendChild(inputDiv);
+
+ inputForm.addEventListener('change', executeCode);
+ }
+
+ function executeCode(e) {
+ try {
+ var result = geval(e.target.value);
+ } catch(e) {
+ var result = 'error — ' + e.message;
+ }
+
+ var outputDiv = document.createElement('div');
+ var outputPara = document.createElement('p');
+
+ outputDiv.setAttribute('class','output');
+ outputPara.textContent = 'Result: ' + result;
+ outputDiv.appendChild(outputPara);
+ document.body.appendChild(outputDiv);
+
+ e.target.disabled = true;
+ e.target.parentNode.style.opacity = '0.5';
+
+ createInput()
+ }
+
+ createInput();
+
+ &lt;/script&gt;
+&lt;/html&gt;</code></pre>
+</div>
+
+<p>{{ EmbedLiveSample('Hidden_code', '100%', 300, "", "", "hide-codepen-jsfiddle") }}</p>
+
+<h3 id="Поиск_длины_строки">Поиск длины строки</h3>
+
+<p>Это легко — вы просто используете свойство {{jsxref ("String.prototype.length", "length")}}. Попробуйте ввести следующие строки:</p>
+
+<pre class="notranslate">let browserType = 'mozilla';
+browserType.length;</pre>
+
+<p>Результатом должно быть число 7, потому что слово «mozilla» состоит из 7 символов. Это свойство можно применить, например, если вы захотите найти длины серии имен, чтобы их можно было отображать по порядку длины или сообщить пользователю, что имя пользователя, которое он ввёл в поле формы, слишком длинное, если оно превышает определённую длину.</p>
+
+<h3 id="Получение_определенного_строкового_символа">Получение определенного строкового символа</h3>
+
+<p>Вы можете вернуть любой символ внутри строки, используя <strong>обозначение в квадратных скобках.</strong> Это означает, что вы добавляете квадратные скобки ([ ]) в конце вашего имени переменной. В квадратных скобках вы указываете номер символа, который хотите вернуть. Например, чтобы получить первую букву, нужно написать:</p>
+
+<pre class="syntaxbox notranslate">browserType[0];</pre>
+
+<p>Компьютеры считают от 0, а не 1! Чтобы получить последний символ <em>любой</em> строки, мы могли бы использовать следующую строку, объединив эту технику с свойством <code>length</code>:</p>
+
+<pre class="syntaxbox notranslate"> browserType[browserType.length-1];</pre>
+
+<p>Длина слова «mozilla» равна 7, но, поскольку счет начинается с 0, позиция последнего символа равна 6, поэтому нам нужна <code>length-1</code>. Такой способ можно использовать, чтобы найти первую букву ряда строк и упорядочить их по алфавиту.</p>
+
+<h3 id="Поиск_подстроки_внутри_строки_и_ее_извлечение">Поиск подстроки внутри строки и ее извлечение</h3>
+
+<ol>
+ <li>Иногда вам может понадобиться выяснить, присутствует ли меньшая строка внутри большей (обычно мы говорим, что внутри строки есть подстрока). Это можно сделать с помощью метода {{jsxref ("String.prototype.indexOf ()", "indexOf ()")}}, который принимает одну {{glossary ("parameter")}} - подстроку, которую вы хотите найти. Введите:
+ <pre class="notranslate">browserType.indexOf('zilla');</pre>
+ Это дает нам результат 2, потому что подстрока «zilla» начинается в позиции 2 ("m" — 0, "o" — 1, "z" — 2) внутри «mozilla». Такой код можно использовать для фильтрации строк. Например, если есть список веб-адресов и вы хотите распечатать только те, которые содержат «mozilla».</li>
+</ol>
+
+<ol start="2">
+ <li>Это можно сделать по-другому, что, возможно, ещё более эффективно. Введите следующее:
+ <pre class="notranslate">browserType.indexOf('vanilla');</pre>
+ Это должно дать вам результат -1. Такое значение возвращается, когда подстрока, в данном случае «vanilla», не найдена в основной строке.<br>
+ <br>
+ Вы можете использовать это, чтобы найти все экземпляры строк, которые не содержат подстроку «mozilla» (для обратного эффекта, используйте оператор отрицания):
+ <pre class="notranslate">if(browserType.indexOf('mozilla') === -1) {
+ // сделать что-то, если 'mozilla'
+ // не является частью этой строки
+}
+
+if(browserType.indexOf('mozilla') !== -1) {
+ // сделать что-то, если 'mozilla'
+ // является частью этой строки
+}</pre>
+ </li>
+ <li>Когда вы знаете, где подстрока начинается внутри строки, и вы знаете, на каком символе вы хотите её завершить, можно использовать {{jsxref ("String.prototype.slice ()", "slice ()")}}  для извлечения. Попробуйте следующее:
+ <pre class="notranslate">browserType.slice(0,3);</pre>
+ Это возвращает «moz». Первым параметром является позиция символа, с которого начинается извлечение, а второй параметр — позиция последнего символа, перед которым нужно отсечь строку<em>.</em> Таким образом, срез происходит с первой позиции, вплоть до последней позиции, но не включая её <em>(</em>помним, что <em>счет идёт с 0, а не с 1)</em>. Также можно сказать, что второй параметр равен длине возвращаемой строки.</li>
+ <li>Кроме того, если вы знаете, что хотите извлечь все остальные символы в строке после определённого символа, вам не нужно включать второй параметр. Достаточно включить только положение символа, с которого вы хотите начать извлечение оставшихся символов в строке. Введите:
+ <pre class="notranslate">browserType.slice(2);</pre>
+ Этот код возвращает «zilla» — это потому, что позиция символа 2 — это буква z, и поскольку вы не указали второй параметр, возвращаемая подстрока состояла из всех остальных символов в строке.</li>
+</ol>
+
+<div class="blockIndicator note">
+<p><strong>Примечание</strong>: второй параметр <code>slice()</code> не обязателен: если вы его не включите в код, обрезание закончится на конце оригинальной строки. Есть и другие варианты; изучите страницу {{jsxref ("String.prototype.slice ()", "slice ()")}}, чтобы узнать, что ещё вы можете узнать.</p>
+</div>
+
+<h3 id="Изменение_регистра">Изменение регистра</h3>
+
+<p>Строковые методы {{jsxref ("String.prototype.toLowerCase ()", "toLowerCase ()")}} и {{jsxref ("String.prototype.toUpperCase ()", "toUpperCase ()")}} преобразовывают все символы в строке в нижний или верхний регистр соответственно. Этот способ можно применить, если вы хотите нормализовать все введенные пользователем данные перед их сохранением в базе данных.</p>
+
+<p>Попробуем ввести следующие строки, чтобы узнать, что происходит:</p>
+
+<pre class="notranslate">var radData = 'My NaMe Is MuD';
+radData.toLowerCase();
+radData.toUpperCase();</pre>
+
+<h3 id="Обновление_частей_строки">Обновление частей строки</h3>
+
+<p>Вы можете заменить одну подстроку внутри строки на другую подстроку, используя метод {{jsxref ("String.prototype.replace ()", "replace ()")}}. Этот метод работает очень просто на базовом уровне, но у него есть некоторые продвинутые свойства, но мы пока не будем вдаваться в детали.</p>
+
+<p>Он принимает два параметра — строку, которую вы хотите заменить, и строку, которую вы хотите вставить вместо заменяемой. Попробуйте этот пример:</p>
+
+<pre class="notranslate">browserType.replace('moz','van');</pre>
+
+<p>Обратите внимание, что для фактического получения обновленного значения, отраженного в переменной browserType в реальной программе, вам нужно будет установить значение переменной в результате операции; он не просто обновляет значение подстроки автоматически. Таким образом, вы должны были бы написать это: <code>browserType = browserType.replace('moz','van');</code></p>
+
+<h2 id="Активные_примеры_обучения">Активные примеры обучения</h2>
+
+<p>В этом разделе мы дадим вам попробовать набить руку и вместе напишем код строковой манипуляции. В каждом упражнении ниже у нас есть массив строк и цикл, который обрабатывает каждое значение в массиве и отображает его в маркированном списке. Вам не нужно понимать массивы или циклы прямо сейчас — это будет объяснено в будущих статьях. Все, что вам нужно сделать в каждом случае, — написать код, который выводит строки в том формате, в котором мы предлагаем.</p>
+
+<p>В каждом примере есть кнопка <em>Сбросить</em>, которую вы можете использовать для сброса кода, если вы допустили ошибку и не можете заставить его работать снова, а кнопку <em>Показать решение</em> вы можете нажать, чтобы увидеть потенциальный ответ, если вы действительно застрянете на решении.</p>
+
+<h3 id="Фильтрация_приветственных_сообщений">Фильтрация приветственных сообщений</h3>
+
+<p>В первом упражнении мы начнем с простого: у нас есть множество сообщений поздравительных открыток, но мы хотим отсортировать их, чтобы перечислять только рождественские сообщения. Мы хотим, чтобы вы заполнили условный тест внутри структуры if( ... ), чтобы проверить каждую строку и отобразить её в списке, только если это рождественское сообщение.</p>
+
+<ol>
+ <li>Сначала подумайте о том, как вы можете проверить, является ли сообщение в каждом случае рождественским сообщением. Какая строка присутствует во всех этих сообщениях и какой метод вы можете использовать для проверки?</li>
+ <li>Затем вам нужно будет написать условный тест <em>операнд1 оператор операнд2</em>. Соответствует ли результат слева результату справа? Или в этом случае вызов метода слева возвращает результат справа?</li>
+ <li>Подсказка. В этом случае, вероятно, полезнее проверить, не является ли часть строки не равной (!==) определенному результату.</li>
+</ol>
+
+<div class="hidden">
+<h6 id="Playable_code">Playable code</h6>
+
+<pre class="brush: html line-numbers language-html notranslate"><code class="language-html">&lt;h2&gt;Результат&lt;/h2&gt;
+
+&lt;div class="output" style="min-height: 125px;"&gt;
+
+&lt;ul&gt;
+
+&lt;/ul&gt;
+
+&lt;/div&gt;
+
+&lt;h2&gt;Редактируемый код&lt;/h2&gt;
+&lt;p class="a11y-label"&gt;</code>Нажмите Esc, чтобы выйти из поля ввода (Tab вставляет символ табуляции).<code class="language-html">&lt;/p&gt;
+
+&lt;textarea id="code" class="playable-code" style="height: 290px; width: 95%"&gt;
+var list = document.querySelector('.output ul');
+list.innerHTML = '';
+var greetings = ['С днём рождения!',
+ 'С Рождеством, любовь моя',
+ 'Счастливого Рождества всей твоей семье',
+ 'Ты — та, кто нужен мне на Рождество',
+ 'Поправляйся скорее'];
+
+for (var i = 0; i &lt; greetings.length; i++) {
+ var input = greetings[i];
+ // Ваше решение должно быть в фигурных скобках
+ // ниже: вы должны что-то добавить
+ if (greetings[i]) {
+ var result = input;
+ var listItem = document.createElement('li');
+ listItem.textContent = result;
+ list.appendChild(listItem);
+ }
+}
+&lt;/textarea&gt;
+
+&lt;div class="playable-buttons"&gt;
+ &lt;input id="reset" type="button" value="Сбросить"&gt;
+ &lt;input id="solution" type="button" value="Показать решение"&gt;
+&lt;/div&gt;</code></pre>
+
+<pre class="brush: css line-numbers language-css notranslate"><code class="language-css">html {
+ font-family: sans-serif;
+}
+
+h2 {
+ font-size: 16px;
+}
+
+.a11y-label {
+ margin: 0;
+ text-align: right;
+ font-size: 0.7rem;
+ width: 98%;
+}
+
+body {
+ margin: 10px;
+ background: #f5f9fa;
+}</code></pre>
+
+<pre class="brush: js line-numbers language-js notranslate"><code class="language-js">var textarea = document.getElementById('code');
+var reset = document.getElementById('reset');
+var solution = document.getElementById('solution');
+var code = textarea.value;
+var userEntry = textarea.value;
+
+function updateCode() {
+ eval(textarea.value);
+}
+
+reset.addEventListener('click', function() {
+ textarea.value = code;
+ userEntry = textarea.value;
+ solutionEntry = jsSolution;
+ solution.value = '</code><code class="language-html">Показать решение</code><code class="language-js">';
+ updateCode();
+});
+
+solution.addEventListener('click', function() {
+ if(solution.value === '</code><code class="language-html">Показать решение</code><code class="language-js">') {
+ textarea.value = solutionEntry;
+ solution.value = '</code><code class="language-html">Спрятать решение</code><code class="language-js">';
+ } else {
+ textarea.value = userEntry;
+ solution.value = '</code><code class="language-html">Показать решение</code><code class="language-js">';
+ }
+ updateCode();
+});
+
+var jsSolution = 'var list = document.querySelector(\'.output ul\');\nlist.innerHTML = \'\';\nvar greetings = [\'</code><code class="language-html">С днём рождения!</code><code class="language-js">\',\n \'</code><code class="language-html">С Рождеством, любовь моя</code><code class="language-js">\',\n \'</code><code class="language-html">Счастливого Рождества всей твоей семье</code><code class="language-js">\',\n \'</code><code class="language-html">Ты — та, кто нужен мне на Рождество</code><code class="language-js">\',\n \'</code><code class="language-html">Поправляйся скорее</code><code class="language-js">\'];\n\nfor(var i = 0; i &lt; greetings.length; i++) {\n var input = greetings[i];\n if(greetings[i].indexOf(\'Рождеств\') !== -1) {\n var result = input;\n var listItem = document.createElement(\'li\');\n listItem.textContent = result;\n list.appendChild(listItem);\n }\n}';
+var solutionEntry = jsSolution;
+
+textarea.addEventListener('input', updateCode);
+window.addEventListener('load', updateCode);
+
+// stop tab key tabbing out of textarea and
+// make it write a tab at the caret position instead
+
+textarea.onkeydown = function(e){
+ if (e.keyCode === 9) {
+ e.preventDefault();
+ insertAtCaret('\t');
+ }
+
+ if (e.keyCode === 27) {
+ textarea.blur();
+ }
+};
+
+function insertAtCaret(text) {
+ var scrollPos = textarea.scrollTop;
+ var caretPos = textarea.selectionStart;
+
+ var front = (textarea.value).substring(0, caretPos);
+ var back = (textarea.value).substring(textarea.selectionEnd, textarea.value.length);
+ textarea.value = front + text + back;
+ caretPos = caretPos + text.length;
+ textarea.selectionStart = caretPos;
+ textarea.selectionEnd = caretPos;
+ textarea.focus();
+ textarea.scrollTop = scrollPos;
+}
+
+// Update the saved userCode every time the user updates the text area code
+
+textarea.onkeyup = function(){
+ // We only want to save the state when the user code is being shown,
+ // not the solution, so that solution is not saved over the user code
+ if(solution.value === '</code><code class="language-html">Показать решение</code><code class="language-js">') {
+ userEntry = textarea.value;
+ } else {
+ solutionEntry = textarea.value;
+ }
+
+ updateCode();
+};</code></pre>
+</div>
+
+<p>{{ EmbedLiveSample('Playable_code', '100%', 590, "", "", "hide-codepen-jsfiddle") }}</p>
+
+<h3 id="Исправление_регистра_размера_букв_в_тексте—прим._пер.">Исправление регистра (<em>размера букв в тексте—прим. пер.</em>)</h3>
+
+<p>В этом упражнении у нас есть названия городов в Великобритании, но написанных разным регистром. Мы хотим, чтобы вы изменили их так, чтобы они были в нижнем регистре, за исключением первой буквы. Хороший способ сделать это:</p>
+
+<ol>
+ <li>Преобразуйте всю строку, содержащуюся в переменной input, в нижний регистр и сохраните ее в новой переменной.</li>
+ <li>Возьмите первую букву строки в этой новой переменной и сохраните ее в другой переменной.</li>
+ <li>Используя эту последнюю переменную в качестве подстроки, замените первую букву строчной строки первой буквой строчной строки, измененной на верхний регистр. Сохраните результат этой процедуры замены в другой новой переменной.</li>
+ <li>Измените значение переменной <code>result</code> на равную конечному результату (не <code>input</code>).</li>
+</ol>
+
+<div class="note">
+<p><strong>Примечание</strong>: Подсказка — параметры строковых методов не обязательно должны быть строковыми литералами; они также могут быть переменными или даже переменными с вызываемым ими методом.</p>
+</div>
+
+<div class="hidden">
+<h6 id="Playable_code_2">Playable code 2</h6>
+
+<pre class="brush: html line-numbers language-html notranslate"><code class="language-html">&lt;h2&gt;Результат&lt;/h2&gt;
+
+&lt;div class="output" style="min-height: 125px;"&gt;
+
+&lt;ul&gt;
+
+&lt;/ul&gt;
+
+&lt;/div&gt;
+
+&lt;h2&gt;Редактируемый код&lt;/h2&gt;
+&lt;p class="a11y-label"&gt;</code>Нажмите Esc, чтобы выйти из поля ввода (Tab вставляет символ табуляции).<code class="language-html">&lt;/p&gt;
+
+&lt;textarea id="code" class="playable-code" style="height: 250px; width: 95%"&gt;
+var list = document.querySelector('.output ul');
+list.innerHTML = '';
+var cities = ['лонДон', 'МанЧЕСТер', 'БиРминГЕМ', 'лиВЕРпуЛЬ'];
+for(var i = 0; i &lt; cities.length; i++) {
+ var input = cities[i];
+ // пишите код ниже
+
+ var result = input;
+ var listItem = document.createElement('li');
+ listItem.textContent = result;
+ list.appendChild(listItem);
+}
+&lt;/textarea&gt;
+
+&lt;div class="playable-buttons"&gt;
+ &lt;input id="reset" type="button" value="Сбросить"&gt;
+ &lt;input id="solution" type="button" value="Показать решение"&gt;
+&lt;/div&gt;</code></pre>
+
+<pre class="brush: css line-numbers language-css notranslate"><code class="language-css">html {
+ font-family: sans-serif;
+}
+
+h2 {
+ font-size: 16px;
+}
+
+.a11y-label {
+ margin: 0;
+ text-align: right;
+ font-size: 0.7rem;
+ width: 98%;
+}
+
+body {
+ margin: 10px;
+ background: #f5f9fa;
+}</code></pre>
+
+<pre class="brush: js line-numbers language-js notranslate"><code class="language-js">var textarea = document.getElementById('code');
+var reset = document.getElementById('reset');
+var solution = document.getElementById('solution');
+var code = textarea.value;
+var userEntry = textarea.value;
+
+function updateCode() {
+ eval(textarea.value);
+}
+
+reset.addEventListener('click', function() {
+ textarea.value = code;
+ userEntry = textarea.value;
+ solutionEntry = jsSolution;
+ solution.value = '</code><code class="language-html">Показать решение</code><code class="language-js">';
+ updateCode();
+});
+
+solution.addEventListener('click', function() {
+ if(solution.value === '</code><code class="language-html">Показать решение</code><code class="language-js">') {
+ textarea.value = solutionEntry;
+ solution.value = 'Спрятать решение';
+ } else {
+ textarea.value = userEntry;
+ solution.value = '</code><code class="language-html">Показать решение</code><code class="language-js">';
+ }
+ updateCode();
+});
+
+var jsSolution = 'var list = document.querySelector(\'.output ul\');\nlist.innerHTML = \'\';\nvar cities = [\'</code><code class="language-html">лонДон</code><code class="language-js">\', \'</code><code class="language-html">МанЧЕСТер</code><code class="language-js">\', \'</code><code class="language-html">БиРминГЕМ</code><code class="language-js">\', \'</code><code class="language-html">лиВЕРпуЛЬ</code><code class="language-js">\'];\n\nfor(var i = 0; i &lt; cities.length; i++) {\n var input = cities[i];\n var lower = input.toLowerCase();\n var firstLetter = lower.slice(0,1);\n var capitalized = lower.replace(firstLetter,firstLetter.toUpperCase());\n var result = capitalized;\n var listItem = document.createElement(\'li\');\n listItem.textContent = result;\n list.appendChild(listItem);\n\n}';
+var solutionEntry = jsSolution;
+
+textarea.addEventListener('input', updateCode);
+window.addEventListener('load', updateCode);
+
+// stop tab key tabbing out of textarea and
+// make it write a tab at the caret position instead
+
+textarea.onkeydown = function(e){
+ if (e.keyCode === 9) {
+ e.preventDefault();
+ insertAtCaret('\t');
+ }
+
+ if (e.keyCode === 27) {
+ textarea.blur();
+ }
+};
+
+function insertAtCaret(text) {
+ var scrollPos = textarea.scrollTop;
+ var caretPos = textarea.selectionStart;
+
+ var front = (textarea.value).substring(0, caretPos);
+ var back = (textarea.value).substring(textarea.selectionEnd, textarea.value.length);
+ textarea.value = front + text + back;
+ caretPos = caretPos + text.length;
+ textarea.selectionStart = caretPos;
+ textarea.selectionEnd = caretPos;
+ textarea.focus();
+ textarea.scrollTop = scrollPos;
+}
+
+// Update the saved userCode every time the user updates the text area code
+
+textarea.onkeyup = function(){
+ // We only want to save the state when the user code is being shown,
+ // not the solution, so that solution is not saved over the user code
+ if(solution.value === '</code><code class="language-html">Показать решение</code><code class="language-js">') {
+ userEntry = textarea.value;
+ } else {
+ solutionEntry = textarea.value;
+ }
+
+ updateCode();
+};</code></pre>
+</div>
+
+<p>{{ EmbedLiveSample('Playable_code_2', '100%', 550, "", "", "hide-codepen-jsfiddle") }}</p>
+
+<h3 id="Создание_новых_строк_из_старых_частей">Создание новых строк из старых частей</h3>
+
+<p>В этом последнем упражнении массив содержит кучу строк, содержащих информацию о железнодорожных станциях на севере Англии. Строки представляют собой элементы данных, которые содержат трехбуквенный код станции, за которым следуют некоторые машиночитаемые данные, за которыми следует точка с запятой, а затем название станции, пригодное для чтения человеком. Например:</p>
+
+<pre class="notranslate">MAN675847583748sjt567654;Manchester Piccadilly</pre>
+
+<p>Мы хотим извлечь код станции и имя и поместить их в строку со следующей структурой:</p>
+
+<pre class="notranslate">MAN: Manchester Piccadilly</pre>
+
+<p>Мы бы рекоменовали реализовать это следующим образом:</p>
+
+<ol>
+ <li>Извлеките трехбуквенный код станции и сохраните его в новой переменной.</li>
+ <li>Найдите номер символьного номера точки с запятой.</li>
+ <li>Извлеките название для чтения человеком, используя номер индекса точки с запятой в качестве контрольной точки и сохраните его в новой переменной.</li>
+ <li>Объедините две новые переменные и строковый литерал, чтобы сделать финальную строку.</li>
+ <li>Измените значение переменной <code>result</code> равной конечной строке (не <code>input</code>). </li>
+</ol>
+
+<div class="hidden">
+<h6 id="Playable_code_3">Playable code 3</h6>
+
+<pre class="brush: html line-numbers language-html notranslate"><code class="language-html">&lt;h2&gt;Результат&lt;/h2&gt;
+
+&lt;div class="output" style="min-height: 125px;"&gt;
+
+&lt;ul&gt;
+
+&lt;/ul&gt;
+
+&lt;/div&gt;
+
+&lt;h2&gt;Редактируемый код&lt;/h2&gt;
+&lt;p class="a11y-label"&gt;</code>Нажмите Esc, чтобы выйти из поля ввода (Tab вставляет символ табуляции).<code class="language-html">&lt;/p&gt;
+
+&lt;textarea id="code" class="playable-code" style="height: 285px; width: 95%"&gt;
+var list = document.querySelector('.output ul');
+list.innerHTML = '';
+var stations = ['MAN675847583748sjt567654;Manchester Piccadilly',
+ 'GNF576746573fhdg4737dh4;Greenfield',
+ 'LIV5hg65hd737456236dch46dg4;Liverpool Lime Street',
+ 'SYB4f65hf75f736463;Stalybridge',
+ 'HUD5767ghtyfyr4536dh45dg45dg3;Huddersfield'];
+
+for (var i = 0; i &lt; stations.length; i++) {
+ var input = stations[i];
+ // пишите ваш код ниже
+
+ var result = input;
+ var listItem = document.createElement('li');
+ listItem.textContent = result;
+ list.appendChild(listItem);
+}
+&lt;/textarea&gt;
+
+&lt;div class="playable-buttons"&gt;
+ &lt;input id="reset" type="button" value="Сбросить"&gt;
+ &lt;input id="solution" type="button" value="Показать решение"&gt;
+&lt;/div&gt;</code></pre>
+
+<pre class="brush: css line-numbers language-css notranslate"><code class="language-css">html {
+ font-family: sans-serif;
+}
+
+h2 {
+ font-size: 16px;
+}
+
+.a11y-label {
+ margin: 0;
+ text-align: right;
+ font-size: 0.7rem;
+ width: 98%;
+}
+
+body {
+ margin: 10px;
+ background: #f5f9fa;
+}</code></pre>
+
+<pre class="brush: js line-numbers language-js notranslate"><code class="language-js">var textarea = document.getElementById('code');
+var reset = document.getElementById('reset');
+var solution = document.getElementById('solution');
+var code = textarea.value;
+var userEntry = textarea.value;
+
+function updateCode() {
+ eval(textarea.value);
+}
+
+reset.addEventListener('click', function() {
+ textarea.value = code;
+ userEntry = textarea.value;
+ solutionEntry = jsSolution;
+ solution.value = '</code><code class="language-html">Показать решение</code><code class="language-js">';
+ updateCode();
+});
+
+solution.addEventListener('click', function() {
+ if(solution.value === '</code><code class="language-html">Показать решение</code><code class="language-js">') {
+ textarea.value = solutionEntry;
+ solution.value = '</code><code class="language-html">Спрятать решение</code><code class="language-js">';
+ } else {
+ textarea.value = userEntry;
+ solution.value = '</code><code class="language-html">Показать решение</code><code class="language-js">';
+ }
+ updateCode();
+});
+
+var jsSolution = 'var list = document.querySelector(\'.output ul\');\nlist.innerHTML = \'\';\nvar stations = [\'MAN675847583748sjt567654;Manchester Piccadilly\',\n \'GNF576746573fhdg4737dh4;Greenfield\',\n \'LIV5hg65hd737456236dch46dg4;Liverpool Lime Street\',\n \'SYB4f65hf75f736463;Stalybridge\',\n \'HUD5767ghtyfyr4536dh45dg45dg3;Huddersfield\'];\n\nfor(var i = 0; i &lt; stations.length; i++) {\n var input = stations[i];\n var code = input.slice(0,3);\n var semiC = input.indexOf(\';\');\n var name = input.slice(semiC + 1);\n var result = code + \': \' + name;\n var listItem = document.createElement(\'li\');\n listItem.textContent = result;\n list.appendChild(listItem);\n}';
+var solutionEntry = jsSolution;
+
+textarea.addEventListener('input', updateCode);
+window.addEventListener('load', updateCode);
+
+// stop tab key tabbing out of textarea and
+// make it write a tab at the caret position instead
+
+textarea.onkeydown = function(e){
+ if (e.keyCode === 9) {
+ e.preventDefault();
+ insertAtCaret('\t');
+ }
+
+ if (e.keyCode === 27) {
+ textarea.blur();
+ }
+};
+
+function insertAtCaret(text) {
+ var scrollPos = textarea.scrollTop;
+ var caretPos = textarea.selectionStart;
+
+ var front = (textarea.value).substring(0, caretPos);
+ var back = (textarea.value).substring(textarea.selectionEnd, textarea.value.length);
+ textarea.value = front + text + back;
+ caretPos = caretPos + text.length;
+ textarea.selectionStart = caretPos;
+ textarea.selectionEnd = caretPos;
+ textarea.focus();
+ textarea.scrollTop = scrollPos;
+}
+
+// Update the saved userCode every time the user updates the text area code
+
+textarea.onkeyup = function(){
+ // We only want to save the state when the user code is being shown,
+ // not the solution, so that solution is not saved over the user code
+ if(solution.value === '</code><code class="language-html">Показать решение</code><code class="language-js">') {
+ userEntry = textarea.value;
+ } else {
+ solutionEntry = textarea.value;
+ }
+
+ updateCode();
+};</code></pre>
+</div>
+
+<p>{{ EmbedLiveSample('Playable_code_3', '100%', 585, "", "", "hide-codepen-jsfiddle") }}</p>
+
+<h2 id="Заключение">Заключение</h2>
+
+<p>Нельзя не согласиться с тем, что способность обрабатывать слова и предложения в программировании очень важна — особенно в JavaScript, поскольку веб-сайты — все связаны с людьми. Эта статья дала вам основы, которые вам нужно знать о манипуляции строками на данный момент. Это пойдет вам на пользу, когда вы займётесь более сложными темами в будущем. Далее мы рассмотрим последний важный тип данных, на который нам нужно сосредоточиться в краткосрочной перспективе — массивы.</p>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/Строки", "Learn/JavaScript/Первые_шаги/Arrays", "Learn/JavaScript/Первые_шаги")}}</p>
+
+<h2 id="В_этом_модуле">В этом модуле</h2>
+
+<ul>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9F%D0%B5%D1%80%D0%B2%D1%8B%D0%B5_%D1%88%D0%B0%D0%B3%D0%B8/What_is_JavaScript">Что такое JavaScript?</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9F%D0%B5%D1%80%D0%B2%D1%8B%D0%B5_%D1%88%D0%B0%D0%B3%D0%B8/A_first_splash">Знакомство с JavaScript</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9F%D0%B5%D1%80%D0%B2%D1%8B%D0%B5_%D1%88%D0%B0%D0%B3%D0%B8/%D0%A7%D1%82%D0%BE_%D0%BF%D0%BE%D1%88%D0%BB%D0%BE_%D0%BD%D0%B5_%D1%82%D0%B0%D0%BA">Устранение ошибок в JavaScript</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9F%D0%B5%D1%80%D0%B2%D1%8B%D0%B5_%D1%88%D0%B0%D0%B3%D0%B8/Variables">Переменные — место хранения необходимой информации</a></li>
+ <li><a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9F%D0%B5%D1%80%D0%B2%D1%8B%D0%B5_%D1%88%D0%B0%D0%B3%D0%B8/Math">Базовая математика в JavaScript</a></li>
+ <li><a href="/ru/docs/Learn/JavaScript/%D0%9F%D0%B5%D1%80%D0%B2%D1%8B%D0%B5_%D1%88%D0%B0%D0%B3%D0%B8/%D0%A1%D1%82%D1%80%D0%BE%D0%BA%D0%B8">Работа с текстом — строки в JavaScript</a></li>
+ <li><a href="/ru/docs/Learn/JavaScript/%D0%9F%D0%B5%D1%80%D0%B2%D1%8B%D0%B5_%D1%88%D0%B0%D0%B3%D0%B8/Useful_string_methods">Полезные строковые методы</a></li>
+ <li><a href="https://wiki.developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9F%D0%B5%D1%80%D0%B2%D1%8B%D0%B5_%D1%88%D0%B0%D0%B3%D0%B8/Arrays">Массивы</a></li>
+ <li><a href="/ru/docs/Learn/JavaScript/%D0%9F%D0%B5%D1%80%D0%B2%D1%8B%D0%B5_%D1%88%D0%B0%D0%B3%D0%B8/%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D1%82%D0%B5%D0%BB%D1%8C_%D0%B3%D0%BB%D1%83%D1%8B%D1%85_%D0%B8%D1%81%D1%82%D0%BE%D1%80%D0%B8%D0%B9">Генератор глупых историй</a></li>
+</ul>
diff --git a/files/ru/learn/javascript/первые_шаги/variables/index.html b/files/ru/learn/javascript/первые_шаги/variables/index.html
new file mode 100644
index 0000000000..e1195effd5
--- /dev/null
+++ b/files/ru/learn/javascript/первые_шаги/variables/index.html
@@ -0,0 +1,372 @@
+---
+title: Переменные - место хранения необходимой информации
+slug: Learn/JavaScript/Первые_шаги/Variables
+translation_of: Learn/JavaScript/First_steps/Variables
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/Что_пошло_не_так", "Learn/JavaScript/Первые_шаги/Math", "Learn/JavaScript/Первые_шаги")}}</div>
+
+<p class="summary">После прочтения последних двух статей вы знаете, что такое JavaScript, что он может сделать для вас, как использовать его вместе с другими веб-технологиями и какими он обладает функциями высокого уровня. В этой статье мы перейдем к реальным основам, рассмотрим, как работать с большинством базовых блоков JavaScript — Переменными.</p>
+
+<table class="learn-box">
+ <tbody>
+ <tr>
+ <th scope="row">Необходимые навыки:</th>
+ <td>Базовая компьютерная грамотность, базовое понимание HTML и CSS, понимание того, что такое JavaScript.</td>
+ </tr>
+ <tr>
+ <th scope="row">Цель:</th>
+ <td>Ознакомиться с основами переменных в JavaScript.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Инструменты_которые_вам_нужны">Инструменты, которые вам нужны</h2>
+
+<p>В этой статье вам будет предложено ввести строки кода, чтобы проверить ваше понимание материала. Если вы используете браузер для настольных компьютеров, лучшим примером для ввода кода примера является консоль JavaScript вашего браузера (см. <a href="/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools">What are browser developer tools</a> для получения дополнительной информации о том, как получить доступ к этому инструменту).</p>
+
+<p>Также мы предоставили простую консоль JavaScript, встроенную ниже в странице, для ввода кода, если вы не используете браузер с консолью JavaScript или консоль на странице окажется для вас более комфортной.</p>
+
+<h2 id="Что_такое_переменные">Что такое переменные?</h2>
+
+<p>Переменные — это контейнер для таких значений, как числа, используемые в сложении, или строка, которую мы могли бы использовать как часть предложения. Но одна из особенностей переменных — их значение может меняться. Давайте взглянем на простой пример:</p>
+
+<pre class="brush: html notranslate">&lt;button&gt;Нажми на меня&lt;/button&gt;</pre>
+
+<pre class="brush: js notranslate">const button = document.querySelector('button');
+
+button.onclick = function() {
+ let name = prompt('Как Вас зовут?');
+ alert('Привет ' + name + ', рады видеть Вас!');
+}</pre>
+
+<p>{{ EmbedLiveSample('What_is_a_variable', '100%', 50, "", "", "hide-codepen-jsfiddle") }}</p>
+
+<p>В примере, по нажатию кнопки выполнится несколько строк кода. Первая строка в функции покажет пользователю окно, где попросит ввести его имя и сохранит значение в переменной. Вторая строка отобразит приветствие с включенным введенным именем, взятым из значения переменной.</p>
+
+<p>Чтобы лучше понять действие переменной здесь, давайте подумаем о том, как мы будем писать этот пример без использования переменной. Это будет выглядеть примерно так:</p>
+
+<pre class="example-bad notranslate">var name = prompt('Как вас зовут?');
+
+if (name === 'Адам') {
+ alert('Привет, Адам, рады тебя видеть!');
+} else if (name === 'Алан') {
+ alert('Привет, Алан, рады тебя видеть!');
+} else if (name === 'Бэлла') {
+ alert('Привет, Бэлла, рады тебя видеть!');
+} else if (name === 'Бьянка') {
+ alert('Привет, Бьянка, рады тебя видеть!');
+} else if (name === 'Крис') {
+ alert('Привет, Крис, рады тебя видеть!');
+}
+
+// ... и так далее ...</pre>
+
+<p>Вам сейчас не обязательно понимать синтаксис, который мы используем (пока!), но вы должны понять идею: если бы у нас не было доступных переменных, нам пришлось бы реализовать гигантский блок кода, который проверял, какое имя было введено, а затем отображал соответствующее сообщение для этого имени. Очевидно, что это неэффективно (код намного больше, даже для четырех вариантов), и он просто не сработает, так как вы не можете хранить все возможные варианты.</p>
+
+<p>Переменные имеют смысл, и, когда вы узнаете больше о JavaScript, они начнут становиться второй натурой.</p>
+
+<p>Еще одна особенность переменных заключается в том, что они могут содержать практически все, а не только строки и числа. Переменные могут также содержать сложные данные и даже целые функции. Об этом вы узнаете больше при дальнейшем изучении курса..</p>
+
+<p>Заметьте: мы говорим, что переменные содержат значения. Это важное различие. Переменные не являются самими значениями; они представляют собой контейнеры для значений. Представьте, что они похожи на маленькие картонные коробки, в которых вы можете хранить вещи.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13506/boxes.png" style="display: block; height: 436px; margin: 0px auto; width: 1052px;"></p>
+
+<h2 id="Объявление_переменной">Объявление переменной</h2>
+
+<p>Чтобы использовать переменную, вы сначала должны ее создать, или, если быть точнее, объявить переменную. Чтобы сделать это, мы вводим ключевое слово var, за которым следует имя, которое вы хотите дать своей переменной:</p>
+
+<pre class="brush: js notranslate">var myName;
+var myAge;</pre>
+
+<p>Здесь мы создаем две переменные myName и myAge. Попробуйте ввести эти строки сейчас в консоли вашего веб-браузера или в консоли ниже (можно открыть эту консоль в отдельной вкладке или в новом окне). После этого попробуйте создать переменную (или две) с вашими именами.</p>
+
+<div class="hidden">
+<h6 id="Hidden_code">Hidden code</h6>
+
+<pre class="brush: html notranslate">&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+ &lt;head&gt;
+ &lt;meta charset="utf-8"&gt;
+ &lt;title&gt;JavaScript console&lt;/title&gt;
+ &lt;style&gt;
+ * {
+ box-sizing: border-box;
+ }
+
+ html {
+ background-color: #0C323D;
+ color: #809089;
+ font-family: monospace;
+ }
+
+ body {
+ max-width: 700px;
+ }
+
+ p {
+ margin: 0;
+ width: 1%;
+ padding: 0 1%;
+ font-size: 16px;
+ line-height: 1.5;
+ float: left;
+ }
+
+ .input p {
+ margin-right: 1%;
+ }
+
+ .output p {
+ width: 100%;
+ }
+
+ .input input {
+ width: 96%;
+ float: left;
+ border: none;
+ font-size: 16px;
+ line-height: 1.5;
+ font-family: monospace;
+ padding: 0;
+ background: #0C323D;
+ color: #809089;
+ }
+
+ div {
+ clear: both;
+ }
+
+ &lt;/style&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+
+
+ &lt;/body&gt;
+
+ &lt;script&gt;
+ var geval = eval;
+ function createInput() {
+ var inputDiv = document.createElement('div');
+ var inputPara = document.createElement('p');
+ var inputForm = document.createElement('input');
+
+ inputDiv.setAttribute('class','input');
+ inputPara.textContent = '&gt;';
+ inputDiv.appendChild(inputPara);
+ inputDiv.appendChild(inputForm);
+ document.body.appendChild(inputDiv);
+
+ if(document.querySelectorAll('div').length &gt; 1) {
+        inputForm.focus();
+      }
+
+ inputForm.addEventListener('change', executeCode);
+ }
+
+ function executeCode(e) {
+ try {
+ var result = geval(e.target.value);
+ } catch(e) {
+ var result = 'error — ' + e.message;
+ }
+
+ var outputDiv = document.createElement('div');
+ var outputPara = document.createElement('p');
+
+ outputDiv.setAttribute('class','output');
+ outputPara.textContent = 'Result: ' + result;
+ outputDiv.appendChild(outputPara);
+ document.body.appendChild(outputDiv);
+
+ e.target.disabled = true;
+ e.target.parentNode.style.opacity = '0.5';
+
+ createInput()
+ }
+
+ createInput();
+
+ &lt;/script&gt;
+&lt;/html&gt;</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Hidden_code', '100%', 300) }}</p>
+
+<div class="note">
+<p><strong>Заметка</strong>: в JavaScript все инструкции кода должны заканчиваться точкой с запятой (;) - ваш код может работать правильно для отдельных строк, но, вероятно, не будет, когда вы пишете несколько строк кода вместе. Попытайтесь превратить написание точки с запятой в привычку.</p>
+</div>
+
+<p>Теперь проверим, существуют ли эти значения в среде выполненияв Для этого введем только имя переменной.</p>
+
+<pre class="brush: js notranslate">myName;
+myAge;</pre>
+
+<p>В настоящее время они не содержат значения, это пустые контейнеры. В этом случае, когда вы вводите имена переменных, вы должны получить значение  <code>undefined</code> . Если они не существуют, вы получите сообщение об ошибке - попробуйте сейчас ввести в консоли имя переменной ниже:</p>
+
+<pre class="brush: js notranslate">scoobyDoo;</pre>
+
+<div class="note">
+<p><strong>Заметка</strong>: Не путайте переменную, которая существует, но не имеет значения, с переменной, которая вообще не существует - это разные вещи.</p>
+</div>
+
+<h2 id="Присвоение_значения_переменной">Присвоение значения переменной</h2>
+
+<p>Как только переменная объявлена, ей можно присвоить значение. Для этого пишется имя переменной, затем следует знак равенства (<code>=</code>), а за ним значение, которое вы хотите присвоить. Например:</p>
+
+<pre class="brush: js notranslate">myName = 'Chris';
+myAge = 37;</pre>
+
+<p>Попробуйте вернуться в консоль и ввести эти строки. Вы должны увидеть значение, которое вы назначили переменной, возвращаемой в консоли. Чтобы посмотреть значения переменных, нужно набрать их имя в консоли:</p>
+
+<pre class="brush: js notranslate">myName;
+myAge;</pre>
+
+<p>Вы можете объявить переменную и задать ей значение одновременно:</p>
+
+<pre class="brush: js notranslate">var myName = 'Chris';</pre>
+
+<p>Скорее всего, так вы будете писать большую часть времени, так как запись и выполнения кода с одно строки происходит быстрее, чем выполнение двух действий на двух отдельных строках.</p>
+
+<div class="note">
+<p><strong>Заметка</strong>: Если вы пишете многострочную программу JavaScript, которая объявляет и инициализирует (задает значение) переменную, вы можете объявить ее после ее инициализации, и она все равно будет работать. Это связано с тем, что объявления переменных обычно выполняются первыми, прежде чем остальная часть кода будет выполнена. Это называется <strong>hoisting </strong>- прочитайте <a href="/en-US/docs/Web/JavaScript/Reference/Statements/var#var_hoisting">var hoisting</a> для более подробной информации по этому вопросу.</p>
+</div>
+
+<h2 id="Обновление_переменной">Обновление переменной</h2>
+
+<p>Когда переменной присваивается значение, вы можете изменить (обновить) это значение, просто указав другое значение. Попробуйте ввести следующие строки в консоль:</p>
+
+<pre class="brush: js notranslate">myName = 'Bob';
+myAge = 40;</pre>
+
+<h3 id="Правила_именования_переменных">Правила именования переменных</h3>
+
+<p>Вы можете назвать переменную как угодно, но есть ограничения. Как правило, вы должны придерживаться только латинских символов (0-9, a-z, A-Z) и символа подчеркивания.</p>
+
+<ul>
+ <li>Не рекомендуется использование других символов, потому что они могут вызывать ошибки или быть непонятными для международной аудитории.</li>
+ <li>Не используйте символы подчеркивания в начале имен переменных - это используется в некоторых конструкциях JavaScript для обозначения конкретных вещей.</li>
+ <li>Не используйте числа в начале переменных. Это недопустимо и приведет к ошибке.</li>
+ <li>Общепринято придерживаться так называемый <a href="https://en.wikipedia.org/wiki/CamelCase#Variations_and_synonyms">"lower camel case"</a>, где вы склеиваете несколько слов, используя строчные буквы для всего первого слова, а затем заглавные буквы последующих слов. Мы использовали это для наших имен переменных в этой статье.</li>
+ <li>Делайте имена переменных такими, чтобы было интуитивно понятно, какие данные они содержат. Не используйте только отдельные буквы / цифры или большие длинные фразы.</li>
+ <li>Переменные чувствительны к регистру, так что <code>myage</code> и <code>myAge</code> - разные переменные.</li>
+ <li>И последнее - вам также нужно избегать использования зарезервированных слов JavaScript в качестве имен переменных - под этим мы подразумеваем слова, которые составляют фактический синтаксис JavaScript! Таким образом, вы не можете использовать слова типа <code>var</code>, <code>function</code>, <code>let</code>, и <code>for</code> для имен переменных. Браузеры распознают их как разные элементы кода, и поэтому возникают ошибки.</li>
+</ul>
+
+<div class="note">
+<p><strong>Заметка</strong>: По ссылке можно найти довольно полный список зарезервированных ключевых слов: <a href="/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Keywords">Lexical grammar — keywords</a>.</p>
+</div>
+
+<p>Примеры хороших имен переменных:</p>
+
+<pre class="example-good notranslate">age
+myAge
+init
+initialColor
+finalOutputValue
+audio1
+audio2
+</pre>
+
+<p>Примеры плохих имен переменных:</p>
+
+<pre class="example-bad notranslate">1
+a
+_12
+myage
+MYAGE
+var
+Document
+skjfndskjfnbdskjfb
+thisisareallylongstupidvariablenameman</pre>
+
+<p>Примеры имен переменных, которые вызовут ошибки:</p>
+
+<pre class="example-invalid notranslate">var
+Document
+</pre>
+
+<p>Попытайтесь создать еще несколько переменных прямо сейчас, используя знания, изложенные выше.</p>
+
+<h2 id="Типы_переменных">Типы переменных</h2>
+
+<p>Есть несколько различных типов данных, которые мы можем хранить в переменных. В этом разделе мы кратко опишем их, а затем в будущих статьях вы узнаете о них более подробно.</p>
+
+<h3 id="Числа_Numbers">Числа (Numbers)</h3>
+
+<p>Вы можете хранить числа в переменных (целые числа, такие как 30, или десятичные числа, такие как 2.456, также называемые числами с плавающей точкой или с плавающей запятой). Вам не нужно объявлять типы переменных в JavaScript, в отличие от некоторых других языков программирования Если давать переменной значение числа,кавычки не используются:</p>
+
+<pre class="brush: js notranslate">var myAge = 17;</pre>
+
+<h3 id="Строки_Strings">Строки ('Strings')</h3>
+
+<p>Строки - это фрагменты текста. Когда вы даете переменной значение строки, вам нужно обернуть ее в одиночные или двойные кавычки, в противном случае JavaScript попытается проиндексировать ее как другое имя переменной.</p>
+
+<pre class="brush: js notranslate">var dolphinGoodbye = 'So long and thanks for all the fish';</pre>
+
+<h3 id="Логические_Booleans">Логические (Booleans)</h3>
+
+<p>Booleans - истинные / ложные значения - они могут иметь два значения: true или false. Они обычно используются для проверки состояния, после чего код запускается соответствующим образом. Вот простой пример:</p>
+
+<pre class="brush: js notranslate">var iAmAlive = true;</pre>
+
+<p>В действительности вы чаще будете использовать этот тип переменных так:</p>
+
+<pre class="brush: js notranslate">var test = 6 &lt; 3;
+</pre>
+
+<p>Здесь используется оператор «меньше» (&lt;), чтобы проверить, является ли 6 меньше 3. В данном примере, он вернет false, потому что 6 не меньше 3! В дальнейшем вы узнаете больше о таких операторах.</p>
+
+<h3 id="Массивы_Arrays">Массивы (Arrays)</h3>
+
+<p>Массив - это один объект, который содержит несколько значений, заключенных в квадратные скобки и разделенных запятыми. Попробуйте ввести следующие строки в консоль:</p>
+
+<pre class="brush: js notranslate">var myNameArray = ['Chris', 'Bob', 'Jim'];
+var myNumberArray = [10,15,40];</pre>
+
+<p>Как только эти массивы определены, можно получить доступ к каждому значению по их местоположению в массиве. Наберите следующие строки:</p>
+
+<pre class="brush: js notranslate">myNameArray[0]; // should return 'Chris'
+myNumberArray[2]; // should return 40</pre>
+
+<p>Квадратные скобки указывают значение индекса, соответствующее позиции возвращаемого значения. Возможно, вы заметили, что массивы в JavaScript индексируются с нулевой отметкой: первый элемент имеет индекс 0.</p>
+
+<p>В следующей статье вы узнаете больше о массивах.</p>
+
+<h3 id="Объекты_Objects">Объекты (Objects)</h3>
+
+<p>В программировании объект представляет собой структуру кода, который моделирует объект реальной жизни. У вас может быть простой объект, представляющий автостоянку, и содержит информацию о её ширине и длине; или вы можете иметь объект, который представляет человека, и содержит данные о его имени, росте, весе, на каком языке он говорит, как сказать ему привет и многое другое.</p>
+
+<p>Попробуйте ввести следующую строку в консоль:</p>
+
+<pre class="brush: js notranslate">var dog = { name : 'Spot', breed : 'Dalmatian' };</pre>
+
+<p>Чтобы получить информацию, хранящуюся в объекте, вы можете использовать следующий синтаксис:</p>
+
+<pre class="brush: js notranslate">dog.name</pre>
+
+<p>Мы больше не будем рассматривать объекты в данном курсе - вы можете больше узнать о них в будущем модуле.</p>
+
+<h2 id="Свободная_типизация">Свободная типизация</h2>
+
+<p>JavaScript - это «свободно типизируемый язык», что означает, что в отличие от некоторых других языков вам не нужно указывать, какой тип данных будет содержать переменная (например, числа, строки, массивы и т. д.).</p>
+
+<p>Например, если вы объявите переменную и присвоите ей значение, заключенное в кавычки, браузер будет обрабатывать переменную как строку:</p>
+
+<pre class="brush: js notranslate">var myString = 'Привет';</pre>
+
+<p>Он все равно будет строкой, даже если он содержит числа, поэтому будьте осторожны:</p>
+
+<pre class="brush: js notranslate">var myNumber = '500'; // упс, это все еще строка (string)
+typeof(myNumber);
+myNumber = 500; // так-то лучше, теперь это число (number)
+typeof(myNumber);</pre>
+
+<p>Попробуйте ввести четыре строки выше в консоль одну за другой и посмотреть результаты. Вы заметите, что мы используем специальную функцию <code>typeof()</code>  - она возвращает тип данных переменной, которую вы передаете в нее. В первый раз, когда она вызывается, она должа возвращать строку, так как переменная <code>myNumber</code> содержит строку <code>'500'</code>. Посмотрите, что она вернет во второй раз, когда вы ее вызовите.</p>
+
+<h2 id="Подведение_итогов">Подведение итогов</h2>
+
+<p>К настоящему времени вы должны знать достаточно о переменных JavaScript и о том, как их создавать. В следующей статье мы остановимся на числах более подробно, рассмотрев, как сделать базовую математику в JavaScript.</p>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/Что_пошло_не_так", "Learn/JavaScript/Первые_шаги/Math", "Learn/JavaScript/Первые_шаги")}}</p>
diff --git a/files/ru/learn/javascript/первые_шаги/what_is_javascript/index.html b/files/ru/learn/javascript/первые_шаги/what_is_javascript/index.html
new file mode 100644
index 0000000000..f34dac6902
--- /dev/null
+++ b/files/ru/learn/javascript/первые_шаги/what_is_javascript/index.html
@@ -0,0 +1,339 @@
+---
+title: Что такое JavaScript?
+slug: Learn/JavaScript/Первые_шаги/What_is_JavaScript
+translation_of: Learn/JavaScript/First_steps/What_is_JavaScript
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{NextMenu("Learn/JavaScript/Первые_шаги/A_first_splash", "Learn/JavaScript/Первые_шаги")}}</div>
+
+<p class="summary">Добро пожаловать на курс MDN JavaScript для начинающих! В первой статье курса мы дадим базовое определение JavaScript, ответим на вопросы «Что такое JavaScript?» и «Что он делает?», узнаем как работает JavaScript и как добавить его на веб-страницу.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Необходимые навыки:</th>
+ <td>Базовая компьютерная грамотность, знание основ HTML и CSS.</td>
+ </tr>
+ <tr>
+ <th scope="row">Цели:</th>
+ <td>Знакомство с JavaScript и его возможностями, способами его подключения к веб-странице.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Определение_высокого_уровня">Определение высокого уровня</h2>
+
+<p>JavaScript это язык, который позволяет Вам применять сложные вещи на web странице — каждый раз, когда на web странице происходит что-то большее, чем просто её статичное отображение — отображение периодически обновляемого контента, или интерактивных карт, или анимация 2D/3D графики, или прокрутка видео в проигрывателе, и т.д. — можете быть уверены, что скорее всего, не обошлось без JavaScript. Это третий слой слоёного пирога стандартных web технологий, два из которых (<a href="https://developer.mozilla.org/ru/docs/Learn/HTML">HTML</a> и <a href="https://developer.mozilla.org/ru/docs/Learn/CSS">CSS</a>) мы детально раскрыли в других частях учебного пособия.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13502/cake.png" style="display: block; margin: 0 auto;"></p>
+
+<ul>
+ <li>{{glossary("HTML")}} - это язык разметки, который мы используем для визуального и смыслового структурирования нашего web контента, например, определяем параграфы, заголовки, таблицы данных, или вставляем изображения и видео на страницу.</li>
+ <li>{{glossary("CSS")}} - это язык стилей с помощью которого мы придаем стиль отображения нашего HTML контента, например придаем цвет фону (background) и шрифту, придаем контенту многоколоночный вид.</li>
+ <li>{{glossary("JavaScript")}} язык программирования, который позволяет Вам создать динамически обновляемый контент, управляет мультимедиа, анимирует изображения, впрочем, делает всё, что угодно. Окей, не все, что угодно, но все равно, это удивительно, что можно достичь с помощью нескольких строк JavaScript кода.</li>
+</ul>
+
+<p>Три слоя прекрасно выстраиваются друг над другом. Возьмем простой текст для примера. Для придания структуры и смыслового назначения тексту, разметим его с помощью HTML:</p>
+
+<pre class="brush: html">&lt;p&gt;Player 1: Chris&lt;/p&gt;</pre>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13422/just-html.png" style="height: 28px; width: 108px;"></p>
+
+<p>Затем мы добавим немного CSS, что бы это выглядело симпатичнее:</p>
+
+<pre class="brush: css">p {
+ font-family: 'helvetica neue', helvetica, sans-serif;
+ letter-spacing: 1px;
+ text-transform: uppercase;
+ text-align: center;
+ border: 2px solid rgba(0,0,200,0.6);
+ background: rgba(0,0,200,0.3);
+ color: rgba(0,0,200,0.6);
+ box-shadow: 1px 1px 2px rgba(0,0,200,0.4);
+ border-radius: 10px;
+ padding: 3px 10px;
+ display: inline-block;
+ cursor:pointer;
+}</pre>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13424/html-and-css.png" style="height: 48px; width: 187px;"></p>
+
+<p>И наконец, добавим немного JavaScript для придания динамического поведения:</p>
+
+<pre>const para = document.querySelector('p');
+
+para.addEventListener('click', updateName);
+
+function updateName() {
+ let name = prompt('Enter a new name');
+ para.textContent = 'Player 1: ' + name;
+}</pre>
+
+<p>{{ EmbedLiveSample('Определение_высокого_уровня', '100%', 80) }}</p>
+
+<p>Попробуйте кликнуть по тексту чтобы увидеть, что произойдет (Вы так же можете найти это демо на GitHub — смотрите <a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/what-is-js/javascript-label.html">исходный код</a>, или <a href="http://mdn.github.io/learning-area/javascript/introduction-to-js-1/what-is-js/javascript-label.html">запустите вживую</a>)!</p>
+
+<p>JavaScript может делать намного больше — давайте выясним это более детально.</p>
+
+<h2 id="Так_что_же_он_действительно_может_делать">Так что же он <em>действительно</em> может делать?</h2>
+
+<p>Ядро языка JavaScript состоит из некоторого количества обычных возможностей, которые позволяют делать следующее:</p>
+
+<ul>
+ <li>Хранить данные внутри переменных. В примере выше, мы, например, запрашивали ввод нового имени, которое нужно было ввести, затем сохраняли имя в переменной <code>name</code>.</li>
+ <li>Операции над фрагментами текстов (известными в программировании как "строки"). В примере выше мы брали строку "Player 1: " и присоединили её к значению переменной <code>name</code> для получения полного текста, например: ''Player 1: Chris".</li>
+ <li>Запускать код в соответствии с определенными событиями происходящими на web странице. В нашем примере выше, мы использовали {{Event("click")}} событие, для определения момента, когда кнопка была кликнута, в соответствии с этим запускался код, который обновлял текст.</li>
+ <li>И многое другое!</li>
+</ul>
+
+<p>Еще более увлекательным является функциональность, созданная поверх основного языка JavaScript. Так называемые интерфейсы прикладного программирования (API) предоставляют вам дополнительные сверхспособности для использования в вашем коде JavaScript.</p>
+
+<p>API - это готовые наборы блоков кода, которые позволяют разработчику реализовывать программы, которые в противном случае было бы трудно или невозможно реализовать. Они делают то же самое для программирования, что готовые комплекты мебели делают для домашнего строительства - гораздо проще брать готовые панели и скручивать их вместе, чтобы сделать книжную полку, чем самому разрабатывать дизайн, ходить в поисках правильной древесины, вырезать все панели необходимого размера и формы, найти подходящие винты, а затем собрать их вместе, чтобы сделать книжную полку.</p>
+
+<p>Они обычно делятся на две категории.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13508/browser.png" style="display: block; height: 511px; margin: 0px auto; width: 815px;"></p>
+
+<p><strong>API-интерфейсы</strong> браузера встроены в ваш веб-браузер и могут отображать данные из окружающего компьютерного окружения или делать полезные сложные вещи. Например:    </p>
+
+<ul>
+ <li>API-интерфейс DOM (Document Object Model) позволяет вам манипулировать HTML и CSS, создавать, удалять и изменять HTML, динамически применять новые стили к вашей странице и т. д.. Каждый раз, когда вы видите всплывающее окно на странице или какое-то новое содержимое, Как мы видели выше в нашем простом демо), например, это DOM в действии.  </li>
+ <li>API геолокации извлекает географическую информацию. Так Google Maps может найти ваше местоположение и нанести его на карту.    </li>
+ <li>API Canvas и WebGL позволяют создавать анимированные 2D и 3D-графики. Люди делают некоторые удивительные вещи, используя эти веб-технологии - см. Chrome Experiments и webglsamples.  </li>
+ <li>Аудио и видео API, такие как {{ domxref("HTMLMediaElement")}} и WebRTC, позволяют делать действительно интересные вещи с мультимедиа, такие как проигрывание аудио и видео прямо на веб-странице, или захватывать видео с веб-камеры и отображать его на Чужой компьютер (попробуйте наш простой демонстрационный снимок, чтобы понять идею)</li>
+</ul>
+
+<div class="note">
+<p><strong>Заметка</strong>: Большинство наших демо не будут корректно работать в старых браузерах — поэтому будет хорошей идеей,  для запуска вашего кода установить один из современных браузеров , таких как Firefox, Chrome, Edge или Opera . Также понадобится более подробно рассмотреть раздел по <a href="https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing">кроссбраузерному тестированию</a>, когда вы приблизитесь к разработке производственного кода (т.е реального кода, который будут использовать клиенты).</p>
+</div>
+
+<p>По умолчанию сторонние API-интерфейсы  не встроены в браузер, и вам придётся захватывать их код и информацию из какого-либо места в Сети. Для примера: </p>
+
+<ul>
+ <li><a href="https://dev.twitter.com/overview/documentation">Twitter API</a> позволяет вам отображать ваши последние твиты на вашем веб-сайте.</li>
+ <li><a href="https://developers.google.com/maps/">Google Maps API</a> позволяет вам встраивать пользовательские карты на ваш сайт и другой подобный функционал.</li>
+</ul>
+
+<div class="note">
+<p><strong>Заметка</strong>: Эти API-и <span style="background-color: #f6d5d9;">являются продвинутыми</span>, и мы не будем их рассматривать в нашем курсе, но ссылки, данные выше, предлагают полную документацию, если вы заинтересованы в более подробной информации.</p>
+</div>
+
+<p>Доступно еще больше! Но пока не заостряйте на этом внимание. Вы не сможете создать следующий Facebook, Google Maps или Instagram после 24 часов изучения JavaScript — сначала нужно изучить основы. И именно для этого вы здесь — давайте двигаться дальше!</p>
+
+<h2 id="Что_JavaScript_делает_на_вашей_странице">Что JavaScript делает на вашей странице?</h2>
+
+<p>В этой главе мы рассмотрим код и увидим что же действительно происходит, когда на странице запускается JavaScript.</p>
+
+<p>Давайте составим краткий бриф, что же происхоит когда мы загружаем страничку в браузере (первое упоминание в статье <a href="/en-US/Learn/CSS/Introduction_to_CSS/How_CSS_works#How_does_CSS_actually_work">Как работает CSS</a>). Когда вы загружаете страничку в браузере, вы запускаете ваш код (HTML, CSS и JavaScript) внутри исполняемой среды (внутри вкладки браузера). Это как будто фабрика берет сырьё (некий код) и выдает продукцию (веб-страничку).</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13504/execution.png" style="display: block; margin: 0 auto;"></p>
+
+<p>Код JavaScript выполняется JavaScript-движком браузера, после того как код HTML и CSS был обработан и сформирован в веб-страницу. Это гарантирует, что структура и стиль страницы уже сформированы к моменту запуска JavaScript.</p>
+
+<p>Это хорошо, так как часто использование JavaScript заключается в динамическом изменении HTML и CSS в целях обновления пользовательского интерфейса посредством Document Object Model API (как упоминалось выше). Если бы запуск JavaScript осуществлялся прежде загрузки HTML и CSS, то это привело бы к возникновению ошибок.  </p>
+
+<h3 id="Безопасность_браузера">Безопасность браузера</h3>
+
+<p>Каждая вкладка браузера представляет собой отдельную коробку для запуска кода (в техническом языке, эти коробки называются "средами исполнения") — это значит, что в большинстве случаев код на каждой вкладке запускается полностью отдельно, а код одной вкладки не может напрямую влиять на код другой вкладки или на другом веб-сайте. Это хорошая мера безопасности — если бы это было иначе, пираты могли написать код, который крал информацию с других сайтов или делал другие плохие вещи.</p>
+
+<div class="note">
+<p><strong>Заметка</strong>: Есть способы отправлять код и данные между разными веб-сайтами/вкладками безопасным способом, но это продвинутые методы, которые мы не будем рассматривать в рамках этого курса.</p>
+</div>
+
+<h3 id="Последовательность_выполнения_JavaScript">Последовательность выполнения JavaScript</h3>
+
+<p>Обычно, когда браузер сталкивается с блоком JavaScript, он запускает его по порядку, сверху вниз. Это значит, что вам нужно осторожно выбирать порядок. Например, вернемся к блоку JavaScript, который мы видели в первом примере:</p>
+
+<pre>const para = document.querySelector('p');
+
+para.addEventListener('click', updateName);
+
+function updateName() {
+ let name = prompt('Enter a new name');
+ para.textContent = 'Player 1: ' + name;
+}</pre>
+
+<p>Здесь мы выбираем абзац текста (строка 1), а затем добавляем к нему обнаружение событий (строка 3), чтобы при нажатии на этот абзац выполнялся блок кода <code>updateName()</code> (строки 5–8). Блок кода <code>updateName()</code> (эти типы <span id="result_box" lang="ru"><span>многократно используемых блоков кода</span></span> называются "функции") запрашивает у пользователя новое имя, а затем вставляет это имя в абзац для обновления отображения.</p>
+
+<p>Если вы поменяете порядок первых двух строк кода, он перестанет работать — вместо этого вы получите ошибку <span id="result_box" lang="ru"><span>возвращаемую в консоль браузера</span></span> — <code>TypeError: para is undefined</code>. Это значит, что объект <code>para</code> еще не существует и вы не можете добавить к нему обнаружение событий.</p>
+
+<div class="note">
+<p><strong>Заметка</strong>: Это очень частая ошибка — вы должны быть осторожны, чтобы объекты, на которые ссылается ваш код, существовали до того, как вы попытаетесь что-то с ними сделать.</p>
+</div>
+
+<h3 id="Интерпретируемый_против_компилируемого_кода">Интерпретируемый против компилируемого кода</h3>
+
+<p>В контексте программирования, вы можете услышать термины <strong>интерпретация</strong> и <strong>компиляция</strong>. JavaScript является <span id="result_box" lang="ru"><span>интерпретируемым языком</span></span> — код запускается сверху вниз и результат запуска немедленно возвращается. Вам не нужно преобразовывать код в другую форму, перед запуском в браузере.</p>
+
+<p><span id="result_box" lang="ru"><span>С другой стороны, к</span></span><span lang="ru"><span>омпилируемые языки преобразуются (компилируются) в другую форму, прежде чем они будут запущены компьютером.</span> <span>Например, C / C ++ компилируются в язык ассемблера, который затем запускается компьютером.</span></span></p>
+
+<p><span id="result_box" lang="ru"><span>Оба подхода имеют разные преимущества, которые на данном этапе мы обсуждать не будем.</span></span></p>
+
+<h3 id="Серверный_против_клиентского_кода">Серверный против клиентского кода</h3>
+
+<p>Вы так же можете услышать термины <strong>серверный</strong> и <strong>клиентский</strong> код, особенно в контексте веб-разработки. Клиентский код — это код, который запускается на компьютере пользователя. При просмотре веб-страницы, клиентский код загружается, а затем запускается и отображается браузером. В этом модуле JavaScript мы явно говорим о <strong>клиентском JavaScript</strong>.</p>
+
+<p>С другой стороны, серверный код запускается на сервере, затем его результаты загружаются и отображаются в браузере. Примеры популярных серверных веб-языков включают PHP, Python, Ruby и ASP.NET. И JavaScript! JavaScript так же может использоваться, как серверный язык, например в популярной среде Node.js — вы можете больше узнать о серверном JavaScript в нашем разделе <a href="/en-US/docs/Learn/Server-side">Dynamic Websites – Server-side programming</a>.</p>
+
+<p>Слово <strong>динамический</strong> используется для описания и клиентского JavaScript, и серверного языка — это относится к возможности обновления отображения веб-страницы/приложения, чтобы показывать разные вещи в разных обстоятельствах, генерируя новый контент по мере необходимости. Серверный код динамически генерирует новый контент на сервере, например достает данные из базы данных, тогда как клиентский JavaScript динамически генерирует новое содержание внутри браузера на клиенте, например создает новую HTML таблицу, вставляя в нее данные полученные с сервера, затем отображает таблицу на веб-странице, которую видит пользователь. В этих двух контекстах значение немного отличается, но связано, и обычно оба подхода (серверный и клиентский) работают вместе.</p>
+
+<p>Веб-страница без динамического обновления контента называется <strong>статической</strong> — она просто показывает один и тотже контент все время.</p>
+
+<h2 id="Как_добавить_JavaScript_на_вашу_страницу">Как добавить JavaScript на вашу страницу?</h2>
+
+<p>JavaScript применяется к вашей HTML странице точно так же, как CSS. И если CSS использует элементы {{htmlelement("link")}} для внешних стилей и {{htmlelement("style")}} для встроеных в HTML, то для JavaScript нужен только один друг в HTML мире — элемент {{htmlelement("script")}}. Давайте узнаем, как это работает.</p>
+
+<h3 id="Внутренний_JavaScript">Внутренний JavaScript</h3>
+
+<ol>
+ <li>Сначала, сделайте локальную копию нашего файла-примера <a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/what-is-js/apply-javascript.html">apply-javascript.html</a>. Сохраните его в удобное для вас место.</li>
+ <li>Откройте этот файл в вашем браузере и в вашем текстовом редакторе. Вы увидите, что HTML создает простую веб-страницу с активной кнопкой.</li>
+ <li>Затем, перейдите в текстовый редактор и добавьте следующие строки перед закрывающим тегом <code>&lt;/head&gt;</code>:
+ <pre class="brush: html">&lt;script&gt;
+
+ // здесь будет JavaScript
+
+&lt;/script&gt;</pre>
+ </li>
+ <li>Теперь добавим JavaScript внутрь элемента {{htmlelement("script")}}, чтобы сделать страницу более интересной — добавьте следующий код ниже строки "// здесь будет JavaScript":
+ <pre>document.addEventListener("DOMContentLoaded", function() {
+ function createParagraph() {
+ let para = document.createElement('p');
+ para.textContent = 'You clicked the button!';
+ document.body.appendChild(para);
+ }
+
+ const buttons = document.querySelectorAll('button');
+
+ for(let i = 0; i &lt; buttons.length ; i++) {
+ buttons[i].addEventListener('click', createParagraph);
+ }
+});</pre>
+ </li>
+ <li>Сохраните файл и обновите страницу в браузере — теперь вы должны увидеть, что при нажатии на кнопку создается новый абзац и помещается ниже.</li>
+</ol>
+
+<div class="note">
+<p><strong>Заметка</strong>: Если ваш пример не работает, пройдите еще раз все шаги и проверьте, сделали ли вы все правильно. Сохранили ли вы вашу локальную копию начального кода, как <code>.html</code> файл? Добавили ли ваш {{htmlelement("script")}} элемент после тэга <code>&lt;/body&gt;</code>? Ввели ли вы JavaScript именно так, как показано? <strong>JavaScript регистрозависимый, и очень привередливый. Поэтому вам нужно вводить синтаксис именно так, как показано, в противном случае оно может не работать.</strong></p>
+</div>
+
+<div class="note">
+<p><strong>Заметка</strong>: Вы можете увидеть эту версию на GitHub-е как <a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/what-is-js/apply-javascript-internal.html">apply-javascript-internal.html</a> (<a href="http://mdn.github.io/learning-area/javascript/introduction-to-js-1/what-is-js/apply-javascript-internal.html">посмотреть вживую</a>).</p>
+</div>
+
+<h3 id="Внешний_JavaScript">Внешний JavaScript</h3>
+
+<p>Это отлично работает, но что если мы хотим поместить наш JavaScript в отдельный файл? Давайте сейчас разберемся с этим.</p>
+
+<ol>
+ <li>Сначала, создайте новый файл в той же папке, что и ваш файл-пример HTML. Назовите его <code>script.js</code> — убедитесь, что у имени файла расширение .js, так как оно распознается, как JavaScript.</li>
+ <li>Замените ваше текущий элемент {{htmlelement("script")}} на следующий:
+ <pre class="brush: html">&lt;script src="script.js" defer&gt;&lt;/script&gt;</pre>
+ </li>
+ <li>Внутри <code>script.js</code> добавьте следующий скрипт:
+ <pre>function createParagraph() {
+ let para = document.createElement('p');
+ para.textContent = 'You clicked the button!';
+ document.body.appendChild(para);
+}
+
+const buttons = document.querySelectorAll('button');
+
+for(let i = 0; i &lt; buttons.length ; i++) {
+ buttons[i].addEventListener('click', createParagraph);
+}</pre>
+ </li>
+ <li>Сохраните и обновите страницу в браузере, и вы увидите то же самое! Все работает точно так же, но теперь у нас есть JavaScript во внешнем файле. Это, как правило, хорошо с точки зрения организации кода и его повторного использования в нескольких HTML файлах. Кроме того, HTML легче читать без огромных кусков кода, который скапливается в нем.</li>
+</ol>
+
+<div class="note">
+<p><strong>Заметка</strong>: Вы можете увидеть эту версию на GitHub-е как <a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/what-is-js/apply-javascript-external.html">apply-javascript-external.html</a> и <a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/what-is-js/script.js">script.js</a> (<a href="http://mdn.github.io/learning-area/javascript/introduction-to-js-1/what-is-js/apply-javascript-external.html">посмотреть вживую</a>).</p>
+</div>
+
+<h3 id="Инлайновые_JavaScript_обработчики">Инлайновые JavaScript обработчики</h3>
+
+<p>Обратите внимание, что иногда можно столкнуться с частями JavaScript кода, который живет внутри HTML. Это может выглядеть примерно так:</p>
+
+<div id="Inline_JavaScript_handlers">
+<pre class="brush: js example-bad">function createParagraph() {
+ var para = document.createElement('p');
+ para.textContent = 'You clicked the button!';
+ document.body.appendChild(para);
+}</pre>
+
+<pre class="brush: html example-bad">&lt;button onclick="createParagraph()"&gt;Click me!&lt;/button&gt;</pre>
+</div>
+
+<p>Вы можете попробовать эту версию в нашей демонстрации ниже:</p>
+
+<p>{{ EmbedLiveSample('Inline_JavaScript_handlers', '100%', 150) }}</p>
+
+<p>Эта демонстрация имеет те же функциональные возможности, что и в предыдущих двух разделах, за исключением того, что элемент {{htmlelement("button")}} содержит встроенный обработчик <code>onclick</code>, который запускает функцию при нажатии кнопки.</p>
+
+<p><strong>Но пожалуйста, не делайте этого.</strong> Это плохая практика — загрязнять ваш HTML кодом JavaScript, и она не эффективна — вам нужно будет добавить атрибут <code>onclick="createParagraph()"</code> к каждой кнопке, к которой вы хотите подключить JavaScript.</p>
+
+<p>Использование чистой JavaScript конструкции, позволит вам выбрать все кнопки, используя одну команду. Код, который можно использовали для этой цели, выглядит следующим образом:</p>
+
+<pre>const buttons = document.querySelectorAll('button');
+
+for(let i = 0; i &lt; buttons.length ; i++) {
+ buttons[i].addEventListener('click', createParagraph);
+}</pre>
+
+<p>Это может выглядеть немного длиннее, чем атрибут <code>onclick</code>, но это будет работать для всех кнопок, независимо от того, сколько их на странице, и сколько их удалят или добавят. JavaScript менять не нужно.</p>
+
+<div class="note">
+<p><strong>Заметка</strong>: Попробуйте отредактировать вашу версию <code>apply-javascript.html</code> и добавить еще несколько кнопок в файл. После перезагрузки вы должны увидеть, что все кнопки создают параграф, если кликнуть на них. Классно, да?</p>
+</div>
+
+<h3 id="Стратегии_загрузки_скриптов">Стратегии загрузки скриптов</h3>
+
+<p>Существует ряд проблем, связанных с загрузкой скриптов в нужное время. Всё не так просто, как кажется! Распространённой проблемой является то, что весь HTML-код на странице загружается в том порядке, в котором отображается. Если вы используете JavaScript для манипуляции элементами на странице (или, точнее, в DOM – Объектной Модели Документа), ваш код не будет работать, если JavaScript-код загрузится и распознается раньше HTML-кода, с которым вы пытаетесь взаимодействовать.</p>
+
+<h2 id="Комментарии">Комментарии</h2>
+
+<p>Так же, как и в HTML и CSS, возможно писать комментарии в вашем JavaScript коде, что будет проигнорировано браузером, и существует только для того, чтобы давать подсказки вашим друзьям-разработчикам о том, как работает код (и лично вам, если вы вернетесь к коду спустя 6 месяцев и не сможете вспомнить, что вы делали). Комментарии очень полезны, и вы должны часто их использовать, особенно для больших приложений. Вот два типа комментариев:</p>
+
+<ul>
+ <li>Однострочный комментарий пишется после двойного слеша (//), например:
+ <pre class="brush: js">// Я комментарий</pre>
+ </li>
+ <li>Комментарий на нескольких строках пишется между строками /* и */, например:
+ <pre class="brush: js">/*
+ Я тоже
+ комментарий
+*/</pre>
+ </li>
+</ul>
+
+<p>Так, например, мы можем описать наш последний демо-пример JavaScript подобными комментариями:</p>
+
+<pre class="brush: js">// Функция: создает новый параграф и добавляет его вниз тела HTML.
+
+function createParagraph() {
+ var para = document.createElement('p');
+ para.textContent = 'You clicked the button!';
+ document.body.appendChild(para);
+}
+
+/*
+ 1. Получаем ссылки на все кнопки на странице в виде массива.
+ 2. Перебераем все кнопки и добавляем к ним отслеживатель события нажатия.
+
+ При нажатии любой кнопки, будет выполняться функция createParagraph().
+*/
+
+var buttons = document.querySelectorAll('button');
+
+for (var i = 0; i &lt; buttons.length ; i++) {
+ buttons[i].addEventListener('click', createParagraph);
+}</pre>
+
+<h2 id="Выводы">Выводы</h2>
+
+<p>Поздравляем, вы сделали ваш первый шаг в мир JavaScript. Мы начали всего-лишь с теории, чтобы вы привыкли к тому, что вы будете использовать JavaScript, и что именно вы можете делать с его помощью. На этом пути вы увидели несколько примеров кода и выучили, как JavaScript вписывается в остальной код на вашем сайте среди всего прочего.</p>
+
+<p>JavaScript может показаться немного пугающим в данным момент, но не переживайте - в этом курсе мы проведем вас сквозь него простыми шагами, которые имеют смысл, забегая наперед. В следующей главе мы <a href="https://developer.mozilla.org/ru/docs/Learn/JavaScript/%D0%9F%D0%B5%D1%80%D0%B2%D1%8B%D0%B5_%D1%88%D0%B0%D0%B3%D0%B8/A_first_splash">погрузимся непосредственно в практику</a>, подталкивая вас погрузиться в код и сделать ваши собственные примеры JavaScript.</p>
+
+<p>{{NextMenu("Learn/JavaScript/Первые_шаги/A_first_splash", "Learn/JavaScript/Первые_шаги")}}</p>
diff --git a/files/ru/learn/javascript/первые_шаги/создатель_глуых_историй/index.html b/files/ru/learn/javascript/первые_шаги/создатель_глуых_историй/index.html
new file mode 100644
index 0000000000..139e478847
--- /dev/null
+++ b/files/ru/learn/javascript/первые_шаги/создатель_глуых_историй/index.html
@@ -0,0 +1,148 @@
+---
+title: Генератор глупых историй
+slug: Learn/JavaScript/Первые_шаги/Создатель_глуых_историй
+tags:
+ - JavaScript
+ - Задание
+ - Изучение
+ - Испытание
+ - Массивы
+ - НаписаниеКода
+ - НачальныйУровень
+ - Операторы
+ - Переменные
+ - Проверка
+ - Числа
+translation_of: Learn/JavaScript/First_steps/Silly_story_generator
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenu("Learn/JavaScript/Первые_шаги/Arrays", "Learn/JavaScript/Первые_шаги")}}</div>
+
+<p class="summary">В этом испытании вам будет нужно, используя знания, полученные в статьях этого модуля, применить их для создания забавного приложения, создающего случайные глупые истории. Удачно повеселиться!</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Требования:</th>
+ <td>Перед началом выполнения этого испытания вам следует проработать все статьи в этом модуле.</td>
+ </tr>
+ <tr>
+ <th scope="row">Задача:</th>
+ <td>Протестировать понимание основ языка JavaScript, таких как переменные, числа, операторы, строки и массивы.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Начальная_точка">Начальная точка</h2>
+
+<p>Для начала испытания вам следует:</p>
+
+<ul>
+ <li>Перейти и <a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/assessment-start/index.html">скопировать файл HTML</a> как пример, сохранив его локальную копию как  <code>index.html</code> в новой папке где-то на вашем компьютере. Там же будет храниться и CSS документ нужный для стилизации.</li>
+ <li>Перейти на <a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/assessment-start/raw-text.txt">страницу, содержащую исходный текст, </a>и оставить ее открытой в отдельной вкладке браузера. Она вам понадобится позже.</li>
+</ul>
+
+<div class="note">
+<p><strong>Замечание</strong>:  Так же вы можете использовать такие сайты как  <a class="external external-icon" href="http://jsbin.com/">JSBin</a> или <a class="external external-icon" href="https://thimble.mozilla.org/">Thimble</a> для выполнения вашего испытания. Вы можете вставить HTML, CSS и JavaScript в один из этих онлайн редакторов. Если онлайн редактор, который вы используете, не имеет отдельного окна для JavaScript - не стесняйтесь вставить все скрипты в <code>&lt;script&gt;</code> элемент внутри  HTML страницы.</p>
+</div>
+
+<h2 id="Краткое_описание_проекта"><span class="short_text" id="result_box" lang="ru"><span>Краткое описание проекта</span></span></h2>
+
+<p><span id="result_box" lang="ru"><span>Вам предоставили некоторый необработанный HTML/CSS, несколько текстовых строк и функций JavaScript;</span> <span>вам необходимо написать необходимый JavaScript код, чтобы превратить это в рабочую программу, которая выполняет следующие действия:</span></span></p>
+
+<ul>
+ <li>Создает глупую историю по нажатию на кнопку "Generate random story".</li>
+ <li>Заменяет стандартное имя "Bob" в истории на свое имя, только если оно введено в поле "Enter custom name" перед тем, как нажата создающая кнопка.</li>
+ <li>Конвертирует изначальные US величины веса и температуры в соответствующие для UK, если выбран соответствующий переключатель.</li>
+ <li>Будет создавать другую глупую историю если нажать на кнопку снова (и снова... )</li>
+</ul>
+
+<p>Следующий скриншот показывает пример того, что должна выводить законченная программа:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13667/assessment-1.png" style="border-style: solid; border-width: 1px; display: block; margin: 0px auto;"></p>
+
+<p>Чтобы вы больше поняли идею <a href="https://mdn.github.io/learning-area/javascript/introduction-to-js-1/assessment-finished/">опробуйте готовый пример</a> (<span class="short_text" id="result_box" lang="ru"><span>не заглядывая в исходный код!</span></span>)</p>
+
+<h2 id="Шаги_к_цели">Шаги к цели</h2>
+
+<p>Следующие разделы описывают, что вам нужно будет сделать.</p>
+
+<p>Начальная подготовка:</p>
+
+<ol>
+ <li>Создайте новый файл под названием <code>main.js</code> в той же папке, что и <code>index.html</code>.</li>
+ <li>Подключите данный JavaScript документ в ваш HTML файл с помощью {{htmlelement("script")}} элемента привязки <code>main.js</code>. Разместите его прямо перед закрывающимся <code>&lt;/body&gt;</code> тегом.</li>
+</ol>
+
+<p>Задайте переменные и функции:</p>
+
+<ol>
+ <li>В исходном текстовом документе скопируйте весь код под заголовком "1. COMPLETE VARIABLE AND FUNCTION DEFINITIONS" и вставьте в начало файла <code>main.js</code>. Это даст вам три переменные, ссылающиеся на текстовое поле "Enter custom name" (<code>customName</code>),  кнопку "Generate random story" (<code>randomize</code>), и элемент снизу HTML страницы, куда будет помещена сама история {{htmlelement("p")}} (<code>story</code>), соответственно. Также у вас должна быть функция<code>randomValueFromArray()</code>, котрая принимает массив и случайным образом возвращает оттуда один из элементов.</li>
+ <li>Теперь взгляните на второй параграф исходного документа — "2. RAW TEXT STRINGS". Он содержит строки текста, которые будут использоваться как входные данные вашей программы. Вам следует поместить их внутрь переменных в файле <code>main.js</code>:
+ <ol>
+ <li>Сохраните первую большую строку текста в переменную <code>storyText</code>.</li>
+ <li>Сохраните первый блок из трех строк как массив, назвав его <code>insertX</code>.</li>
+ <li>Сохраните второй блок из трех строк как массив, назвав его <code>insertY</code>.</li>
+ <li>Сохраните третий блок из трех строк как массив, назвав его <code>insertZ</code>.</li>
+ </ol>
+ </li>
+</ol>
+
+<p>Создание обработчика событий и неполной функции:</p>
+
+<ol>
+ <li>Теперь возвращаемся к исходному текстовому файлу.</li>
+ <li>Скопируйте код под заголовком "3. EVENT LISTENER AND PARTIAL FUNCTION DEFINITION" и вставте его в конец файла <code>main.js</code>. Это:
+ <ul>
+ <li>Добавит обработчик события кликанья в переменную <code>randomize</code>,  Так что, когда кнопка будет нажата -  функция <code>result()</code> запустится.</li>
+ <li>Добавляет в код частично завершенную функцию <code>result()</code>. В течении оставшейся части испытания вам предстоит, заполняя строчки внутри этой функции, завершить ее и заставить работать должным образом.</li>
+ </ul>
+ </li>
+</ol>
+
+<p>Завершение функции <code>result()</code>:</p>
+
+<ol>
+ <li>Создайте новую переменную <code>newStory</code> и установите ее значение равным <code>storyText</code>. Это необходимо, чтобы мы могли создавать новую случайную историю каждый раз, когда нажимается кнопка, и функция запускается. Если бы мы внесли изменения непосредственно в <code>storyText</code>, мы могли бы генерировать новую историю только один раз.</li>
+ <li>Создайте три новые переменные, называемые <code>xItem</code>, <code>yItem</code> и <code>zItem</code>, и сделайте их равными результату вызова <code>randomValueFromArray()</code> на трех ваших массивах (результат в каждом случае будет случайным элементом из каждого массива, на который он вызывается). Например, вы можете вызвать функцию и получить ее, чтобы вернуть одну случайную строку из <code>insertX</code>, записав <code>randomValueFromArray (insertX)</code>.</li>
+ <li>Затем мы хотим заменить три заполнителя строки <code>newStory</code> - <code>:insertx:</code>, <code>:inserty :</code>  и <code>:insertz:</code> - со строками, хранящимися в <code>xItem</code>, <code>yItem</code> и <code>zItem</code>. Здесь вам поможет определенный строковый метод - в каждом случае сделать вызов метода равным <code>newStory</code>, при этом каждый раз, когда он вызывается, <code>newStory</code> делается равным самому себе, но с выполненными заменами. Поэтому каждый раз, когда нажимается кнопка, эти заполнители заменяются случайной строкой. Подсказка: рассматриваемый метод заменяет только первый экземпляр найденной подстроки, поэтому вам, возможно, придется сделать один из вызовов дважды.</li>
+ <li>Внутри первого блока <code>if</code> добавьте другой метод замены строки, чтобы заменить имя «Боб», найденное в строке <code>newStory</code>, с помощью переменной <code>name</code>. В этом блоке мы говорим: «Если значение введено в текстовый ввод <code>customName</code>, замените Боба в истории этим пользовательским именем».</li>
+ <li>Внутри второго блока <code>if</code> мы проверяем, была ли выбрана радиокнопка <code>uk</code>. Если это так, мы хотим преобразовать значения веса и температуры в историю из фунтов и Фаренгейта в метры и по Цельсию. Что вам нужно сделать, так это:
+ <ol>
+ <li>Посмотрите формулу преобразования фунтов в стоуны и Фаренгейта в по Цельсию.</li>
+ <li>Внутри линии, которая определяет <code>weight</code> переменную, замените 300 на расчет, который преобразует 300 фунтов в стоуны. Добавьте <code>'stone'</code> в конце результата общего вызова <code>Math.round()</code>.</li>
+ <li>Внутри линии, определяющей <code>temperature</code> переменную, замените 94 на расчет, который преобразует 94 градуса по Фаренгейту в по Цельсию. Добавьте <code>'centigrade'</code> в конце результата общего вызова <code>Math.round()</code>.</li>
+ <li>Просто под двумя определениями переменных добавьте еще две строки замены строк, которые заменяют «94 farenheit» на содержимое переменной <code>temperature</code> и«300  pounds» на содержимое <code>weight</code> переменной.</li>
+ </ol>
+ </li>
+ <li>Наконец, в предпоследней строке функции сделайте свойство <code>textContent</code> переменной <code>story</code> (которая ссылается на абзац) равным <code>newStory</code>.</li>
+</ol>
+
+<h2 id="Советы_и_подсказки">Советы и подсказки</h2>
+
+<ul>
+ <li>Вам не нужно каким-либо образом редактировать HTML, кроме как применять JavaScript к вашему HTML.</li>
+ <li>Если вы не уверены, правильно ли применяется JavaScript для вашего HTML-кода, попробуйте временно удалить все остальное из файла JavaScript, добавив в него простой кусочек JavaScript, который, как вы знаете, создаст очевидный эффект, а затем сохраните и обновите. Следующий, например, делает фон элемента {{htmlelement ("html")}} красного цвета - поэтому все окно браузера должно быть красным, если JavaScript применяется правильно:
+ <pre class="brush: js notranslate">document.querySelector('html').style.backgroundColor = 'red';</pre>
+ </li>
+ <li><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round">Math.round()</a> - это встроенный метод JavaScript, который просто округляет результат вычисления до ближайшего целого числа.</li>
+</ul>
+
+<h2 id="Оценка_и_помощь">Оценка и помощь</h2>
+
+<p><span class="tlid-translation translation" lang="ru"><span title="">Если вы хотите, чтобы ваша работа была оценена, или застряли и хотите обратиться за помощью:</span></span></p>
+
+<ol>
+ <li>Разместите свою работу в онлайн-редакторе, таком как <a href="https://codepen.io/">CodePen</a>, <a href="https://jsfiddle.net/">jsFiddle </a>или <a href="https://glitch.com/">Glitch</a>.</li>
+ <li><span class="tlid-translation translation" lang="ru"><span title="">Напишите сообщение с просьбой об оценке и / или помощи на форуме <a href="https://discourse.mozilla.org/c/mdn">MDN Discourse</a>.</span> <span title="">Добавьте тег «learning» к своему сообщению, чтобы мы могли легче его найти.</span> <span title="">Ваш пост должен включать:</span></span>
+ <ul>
+ <li><span class="tlid-translation translation" lang="ru"><span title="">Описательное название, такое как «Требуется оценка для генератора глупых историй».</span></span></li>
+ <li><span class="tlid-translation translation" lang="ru"><span title="">Подробная информация о том, что вы хотели бы, чтобы мы делали, например, что вы уже пробовали, если вы застряли и нуждаетесь в помощи.</span></span></li>
+ <li><span class="tlid-translation translation" lang="ru"><span title="">Ссылка на пример, который вы хотите оценить или нуждаетесь в помощи, в онлайн-редакторе.</span> <span title="">Это хорошая практика - очень сложно помочь кому-то с проблемой кодирования, если вы не видите его код.</span></span></li>
+ <li><span class="tlid-translation translation" lang="ru"><span title="">Ссылка на актуальную задачу или страницу оценки, чтобы мы могли найти вопрос, с которым вы хотите помочь.</span></span></li>
+ </ul>
+ </li>
+</ol>
+
+<p>{{PreviousMenu("Learn/JavaScript/Первые_шаги/Arrays", "Learn/JavaScript/Первые_шаги")}}</p>
diff --git a/files/ru/learn/javascript/первые_шаги/строки/index.html b/files/ru/learn/javascript/первые_шаги/строки/index.html
new file mode 100644
index 0000000000..583e29182e
--- /dev/null
+++ b/files/ru/learn/javascript/первые_шаги/строки/index.html
@@ -0,0 +1,284 @@
+---
+title: Работа с текстом — строки в JavaScript
+slug: Learn/JavaScript/Первые_шаги/Строки
+translation_of: Learn/JavaScript/First_steps/Strings
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/Math", "Learn/JavaScript/Первые_шаги/Useful_string_methods", "Learn/JavaScript/Первые_шаги")}}</div>
+
+<p class="summary">Теперь мы обратим внимание на строки — в программировании так называют части текста. В этой статье мы рассмотрим все распростанённые вещи, которые вы должны действительно знать о строках при изучении JavaScript, например, создание строк, <span id="result_box" lang="ru"><span>экранирование кавычек в строках и объединение строк вместе.</span></span></p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Необходимые навыки:</th>
+ <td>Базовая компьютерная грамотность, базовое понимание HTML и CSS, понимание что такое JavaScript.</td>
+ </tr>
+ <tr>
+ <th scope="row">Цель:</th>
+ <td><span class="short_text" id="result_box" lang="ru"><span>Знакомство с основами строк в JavaScript.</span></span></td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Сила_слов">Сила слов</h2>
+
+<p><span id="result_box" lang="ru"><span>Слова очень важны для людей </span></span>—<span lang="ru"><span> это основа нашего общения.</span></span> <span class="short_text" id="result_box" lang="ru"><span>Интернет</span></span> <span id="result_box" lang="ru"><span>представляет собой преимущественно текстовую среду, предназначенную для</span></span> того что бы люди общались и делились информацией, поэтому <span id="result_box" lang="ru"><span>нам полезно иметь контроль над словами, которые появляются в нем.</span></span> {{glossary ("HTML")}} предоставляет визуальную и смысловую структуру для нашего текста, {{glossary ("CSS")}} позволяет нам стилизовать его, а JavaScript содержит ряд функций для управления строками, создания пользовательских приветственных сообщений, при необходимости отображая нужные текстовые метки, сортируя элементы в желаемом порядке и многое другое.</p>
+
+<p>Практически во всех программах, которые мы показали вам на данный момент,  были задействованы некоторые манипуляции со строками.</p>
+
+<h2 id="Строки_—_основы">Строки — основы</h2>
+
+<p>С первого взгляда строки обрабатываются аналогично числам, но если копнуть глубже, вы увидите некоторые заметные отличия. Давайте начнем с ввода некоторых основных строк в консоль, чтобы ознакомиться с ними. Мы предоставили одну ниже (вы также можете <a href="https://mdn.github.io/learning-area/javascript/introduction-to-js-1/variables/index.html">открыть эту консоль</a> в отдельной вкладке или окне или использовать <a href="/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools">консоль разработчика браузера</a>, если хотите).</p>
+
+<div class="hidden">
+<h6 id="Hidden_code">Hidden code</h6>
+
+<pre class="brush: html notranslate">&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+ &lt;head&gt;
+ &lt;meta charset="utf-8"&gt;
+ &lt;title&gt;JavaScript console&lt;/title&gt;
+ &lt;style&gt;
+ * {
+ box-sizing: border-box;
+ }
+
+ html {
+ background-color: #0C323D;
+ color: #809089;
+ font-family: monospace;
+ }
+
+ body {
+ max-width: 700px;
+ }
+
+ p {
+ margin: 0;
+ width: 1%;
+ padding: 0 1%;
+ font-size: 16px;
+ line-height: 1.5;
+ float: left;
+ }
+
+ .input p {
+ margin-right: 1%;
+ }
+
+ .output p {
+ width: 100%;
+ }
+
+ .input input {
+ width: 96%;
+ float: left;
+ border: none;
+ font-size: 16px;
+ line-height: 1.5;
+ font-family: monospace;
+ padding: 0;
+ background: #0C323D;
+ color: #809089;
+ }
+
+ div {
+ clear: both;
+ }
+
+ &lt;/style&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+
+
+ &lt;/body&gt;
+
+ &lt;script&gt;
+ var geval = eval;
+ function createInput() {
+ var inputDiv = document.createElement('div');
+ var inputPara = document.createElement('p');
+ var inputForm = document.createElement('input');
+
+ inputDiv.setAttribute('class','input');
+ inputPara.textContent = '&gt;';
+ inputDiv.appendChild(inputPara);
+ inputDiv.appendChild(inputForm);
+ document.body.appendChild(inputDiv);
+
+ if(document.querySelectorAll('div').length &gt; 1) {
+        inputForm.focus();
+      }
+
+ inputForm.addEventListener('change', executeCode);
+ }
+
+ function executeCode(e) {
+ try {
+ var result = geval(e.target.value);
+ } catch(e) {
+ var result = 'error — ' + e.message;
+ }
+
+ var outputDiv = document.createElement('div');
+ var outputPara = document.createElement('p');
+
+ outputDiv.setAttribute('class','output');
+ outputPara.textContent = 'Result: ' + result;
+ outputDiv.appendChild(outputPara);
+ document.body.appendChild(outputDiv);
+
+ e.target.disabled = true;
+ e.target.parentNode.style.opacity = '0.5';
+
+ createInput()
+ }
+
+ createInput();
+
+ &lt;/script&gt;
+&lt;/html&gt;</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Hidden_code', '100%', 300) }}</p>
+
+<h3 id="Создание_строки">Создание строки</h3>
+
+<ol>
+ <li>Для начала введите следующие строки:
+ <pre class="brush: js notranslate">var string = 'The revolution will not be televised.';
+string;</pre>
+ </li>
+ <li>Как и в случае с числами, мы объявляем переменную, инициализируя ее строковым значением, а затем возвращаем значение. Единственное различие здесь в том, что при написании строки вам нужно окружить значение кавычками. </li>
+ <li>Если вы не сделаете этого или пропустите одну из кавычек, вы получите сообщение об ошибке. Попробуйте ввести следующие строки:
+ <pre class="brush: js example-bad notranslate">var badString = This is a test;
+var badString = 'This is a test;
+var badString = This is a test';</pre>
+ Эти строки не работают, потому что любая текстовая строка без кавычек считается именем переменной, именем свойства, зарезервированным словом или чем-то подобным. Если браузер не может найти его, возникает ошибка (например, «missing, before statement»). Если браузер может видеть, где начинается строка, но не может найти конец строки, как указано во 2-й строке, она жалуется на ошибку (с «unterminated string literal»). Если ваша программа выявляет такие ошибки, вернитесь назад и проверьте все свои строки, чтобы убедиться, что у вас нет пропущенных кавычек.</li>
+ <li>Следующий код будет выполнен только в том случае, если ранее была объявлена переменная <code>string</code> — убедитесь сами:
+ <pre class="brush: js notranslate">var badString = string;
+badString;</pre>
+ В настоящее время строка <code>badString</code> имеет то же значение, что и строка <code>string</code>.</li>
+</ol>
+
+<h3 id="Одиночные_кавычки_vs._Двойные_кавычки">Одиночные кавычки vs. Двойные кавычки</h3>
+
+<ol>
+ <li>В JavaScript вы можете выбрать одинарные кавычки или двойные кавычки, чтобы обернуть ваши строки. Оба варианта будут работать нормально:
+ <pre class="brush: js notranslate">var sgl = 'Single quotes.';
+var dbl = "Double quotes";
+sgl;
+dbl;</pre>
+ </li>
+ <li>Существует очень мало различий между одиночными и двойными кавычками, и решение какие из них использовать в коде остается на ваше усмотрение. Однако вы должны выбрать один вариант и придерживаться его, иначе ваш код может выдать ошибку, особенно если вы используете разные кавычки в одной строке! Ниже приведен пример:
+ <pre class="brush: js example-bad notranslate">var badQuotes = 'What on earth?";</pre>
+ </li>
+ <li>Браузер будет считать, что строка не была закрыта, потому что в строке может появиться другой тип цитаты, который вы не используете, чтобы хранить ваши строки в переменных. Из примера можно понять, о чем идет речь (в коде ошибок нет):
+ <pre class="brush: js notranslate">var sglDbl = 'Would you eat a "fish supper"?';
+var dblSgl = "I'm feeling blue.";
+sglDbl;
+dblSgl;</pre>
+ </li>
+ <li>Однако вы не можете включить один и тот же знак кавычки внутри строки, если он используется для их хранения. Ниже приведена ошибка, браузер ошибочно определяет место, где строка кончается:
+ <pre class="brush: js example-bad notranslate">var bigmouth = 'I've got no right to take my place...';</pre>
+ Что приводит нас к следующей теме.</li>
+</ol>
+
+<h3 id="Экранирование_кавычек_в_строках">Экранирование кавычек в строках</h3>
+
+<p>Чтобы исправить нашу предыдущую строку кода, нам нужно дать понять браузеру, что кавычка в середине строки не является меткой ее конца. Экранирование символов означает, что мы делаем что-то с ними, чтобы убедиться, что они распознаются как текст, а не часть кода. В JavaScript мы делаем это, помещая обратную косую черту непосредственно перед символом. Введите эти строки:</p>
+
+<pre class="brush: js notranslate">var bigmouth = 'I\'ve got no right to take my place...';
+bigmouth;</pre>
+
+<p>Так лучше. Таким же образом можно экранировать и другие символы, например <code>"\</code>. Кроме того существуют специальные коды. Для дополнительной информации см. <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#Escape_notation">Escape notation</a>.</p>
+
+<h2 id="Конкатенация_строк">Конкатенация строк</h2>
+
+<ol>
+ <li>Конкатенация — это новомодное программистское слово, которое означает «объединить». Объединение строк в JavaScript использует оператор плюс (+), тот же, который мы используем для сложения чисел, но в этом контексте он делает кое-что другое. Попробуем пример в нашей консоли.</li>
+ <li>
+ <pre class="brush: js notranslate">var one = 'Hello, ';
+var two = 'how are you?';
+var joined = one + two;
+joined;</pre>
+ Результат этой программы - это переменная <code>joined</code>, содержащая значение "Hello, how are you?".</li>
+ <li>В последнем случае мы просто объединим две строки вместе, но на самом деле, вы можете объединить столько строк, сколько хотите, до тех пор, пока вы ставите <code>+</code> между ними. Попробуйте это:
+ <pre class="brush: js notranslate">var multiple = one + one + one + one + two;
+multiple;</pre>
+ </li>
+ <li>Вы также можете использовать сочетание переменных и фактических строк. Попробуйте это:
+ <pre class="brush: js notranslate">var response = one + 'I am fine — ' + two;
+response;</pre>
+ </li>
+</ol>
+
+<div class="note">
+<p><strong>Примечание: </strong>Когда вы вводите фактическую строку в свой код, заключенную в одинарные или двойные кавычки, она называется <strong>строковым литералом.</strong></p>
+</div>
+
+<h3 id="Конкатенация_строк_в_контексте">Конкатенация строк в контексте</h3>
+
+<p>Давайте посмотрим на конкатенацию строк в действии — вот пример из предыдущего курса:</p>
+
+<pre class="brush: html notranslate">&lt;button&gt;Press me&lt;/button&gt;</pre>
+
+<pre class="brush: js notranslate">var button = document.querySelector('button');
+
+button.onclick = function() {
+ var name = prompt('What is your name?');
+ alert('Hello ' + name + ', nice to see you!');
+}</pre>
+
+<p>{{ EmbedLiveSample('Concatenation_in_context', '100%', 50) }}</p>
+
+<p>Здесь мы используем функцию {{domxref ("Window.prompt ()", "Window.prompt ()")}} в строке 4, которая просит пользователя ответить на вопрос через всплывающее диалоговое окно, а затем сохраняет введенный текст внутри заданной переменной — в этом случае <code><strong>name</strong></code>. Затем мы используем функцию {{domxref ("Window.alert ()", "Window.alert ()")}} в строке 5 для отображения другого всплывающего окна, содержащего строку, которую мы собрали из двух строковых литералов и переменной <code>name</code>.</p>
+
+<h3 id="Числа_vs._строки">Числа vs. строки</h3>
+
+<ol>
+ <li>Итак, что происходит, когда мы пытаемся добавить (или конкатенировать) строку и число? Попробуем это в нашей консоли:
+ <pre class="brush: js notranslate">'Front ' + 242;
+</pre>
+ Вы можете ожидать, что это вызовет ошибку, но все работает отлично. Попытка представить строку как число на самом деле не имеет смысла, но число как строку — имеет, поэтому браузер довольно умно преобразует число в строку и объединяет две строки вместе.</li>
+ <li>Вы даже можете сделать это с двумя числами, вы можете заставить число стать строкой, обернув ее в кавычки. Попробуйте следующее (мы используем оператор <code>typeof</code> для того, чтобы установить является ли переменная числом или строкой):
+ <pre class="brush: js notranslate">var myDate = '19' + '67';
+typeof myDate;</pre>
+ </li>
+ <li>Если у вас есть числовая переменная, которую вы хотите преобразовать в строчную без внесения каких-либо иных изменений или строковую переменную, которую вы хотите преобразовать в число, вы можете использовать следующие две конструкции:
+ <ul>
+ <li>Объект {{jsxref ("Number")}} преобразует всё переданное в него в число, если это возможно. Попробуйте следующее:
+ <pre class="brush: js notranslate">var myString = '123';
+var myNum = Number(myString);
+typeof myNum;</pre>
+ </li>
+ <li>С другой стороны, каждое число имеет метод, называемый <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString">toString()</a></code>, который преобразует его в эквивалентную строку. Попробуй это:
+ <pre class="brush: js notranslate">var myNum = 123;
+var myString = myNum.toString();
+typeof myString;</pre>
+ </li>
+ </ul>
+ Эти конструкции могут быть действительно полезны в некоторых ситуациях. Например, если пользователь вводит число в текстовое поле формы, данные будут распознаны как строка. Однако, если вы хотите добавить это число к чему-то, вам понадобится его значение, поэтому вы можете передать его через <code>Number()</code>, чтобы справиться с этим. Именно это мы сделали в нашей <a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/first-splash/number-guessing-game.html#L63">Number Guessing Game,  </a>в строке 61.</li>
+</ol>
+
+<h2 id="Заключение">Заключение</h2>
+
+<p>Итак, это основы строк, используемых в JavaScript. В следующей статье мы рассмотрим некоторые из встроенных методов, доступных для строк в JavaScript и то, как мы можем использовать их для управления нашими строками только в той форме, в которой мы хотим.</p>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/Math", "Learn/JavaScript/Первые_шаги/Useful_string_methods", "Learn/JavaScript/Первые_шаги")}}</div>
+
+<h2 id="В_этом_модуле">В этом модуле</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/What_is_JavaScript">What is JavaScript?</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/A_first_splash">A first splash into JavaScript</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/What_went_wrong">What went wrong? Troubleshooting JavaScript</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Variables">Storing the information you need — Variables</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Math">Basic math in JavaScript — numbers and operators</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Strings">Handling text — strings in JavaScript</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Useful_string_methods">Useful string methods</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Arrays">Arrays</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Silly_story_generator">Assessment: Silly story generator</a></li>
+</ul>
diff --git a/files/ru/learn/javascript/первые_шаги/что_пошло_не_так/index.html b/files/ru/learn/javascript/первые_шаги/что_пошло_не_так/index.html
new file mode 100644
index 0000000000..dbb0a4577a
--- /dev/null
+++ b/files/ru/learn/javascript/первые_шаги/что_пошло_не_так/index.html
@@ -0,0 +1,249 @@
+---
+title: Что пошло не так? Устранение ошибок JavaScript
+slug: Learn/JavaScript/Первые_шаги/Что_пошло_не_так
+translation_of: Learn/JavaScript/First_steps/What_went_wrong
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/A_first_splash", "Learn/JavaScript/Первые_шаги/Variables", "Learn/JavaScript/Первые_шаги")}}</div>
+
+<p class="summary">Когда вы создали игру «Угадай номер» в предыдущей статье, вы, возможно, обнаружили, что она не работает. Не бойтесь — эта статья призвана избавить вас от разрыва волос над такими проблемами, предоставив вам несколько простых советов о том, как найти и исправить ошибки в программах JavaScript.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">
+ <p>Нужно:</p>
+ </th>
+ <td>базовая компьютерная грамотность, базовое понимание HTML и CSS, понимание того, что такое JavaScript.</td>
+ </tr>
+ <tr>
+ <th scope="row">Цель</th>
+ <td>получить способность и уверенность в том, чтобы приступить к исправлению простых проблем в вашем собственном коде.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Типы_ошибок">Типы ошибок</h2>
+
+<p>Когда вы делаете что-то не так в коде, есть два основных типа ошибок, с которыми вы столкнетесь:</p>
+
+<ul>
+ <li>
+ <p><strong>Синтаксические ошибки:</strong> Это орфографические ошибки в коде, которые фактически заставляют программу вообще не запускаться, или перестать работать на полпути — вам также будут предоставлены некоторые сообщения об ошибках. Обычно они подходят для исправления, если вы знакомы с правильными инструментами и знаете, что означают сообщения об ошибках!</p>
+ </li>
+ <li><strong>Логические ошибки:</strong> Это ошибки, когда синтаксис действительно правильный, но код не тот, каким вы его предполагали, что означает, что программа работает успешно, но дает неверные результаты. Их часто сложнее находить, чем синтаксические ошибки, так как обычно не возникает сообщение об ошибке, которое направляет вас к источнику ошибки.</li>
+</ul>
+
+<p>Ладно, все <em>не так</em> просто — есть и другие отличия, которые вы поймете, пока будете изучать язык JavaScript глубже. Однако вышеуказанной классификации достаточно на раннем этапе вашей карьеры. Мы рассмотрим оба эти типа в дальнейшем.</p>
+
+<h2 id="Ошибочный_пример">Ошибочный пример</h2>
+
+<p>Чтобы начать работу, давайте вернемся к нашей игре с угадыванием чисел — за исключением того, что мы будем изучать версию с некоторыми преднамеренными ошибками. Перейдите в Github и сделайте себе локальную копию <a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/troubleshooting/number-game-errors.html">number-game-errors.html</a> (см. здесь <a href="http://mdn.github.io/learning-area/javascript/introduction-to-js-1/troubleshooting/number-game-errors.html">как это работает</a>).</p>
+
+<ol>
+ <li>Чтобы начать работу, откройте локальную копию внутри вашего любимого текстового редактора и вашего браузера.</li>
+ <li>Попробуйте сыграть в игру — вы заметите, что когда вы нажимаете кнопку «Submit guess», она не работает!</li>
+</ol>
+
+<div class="note">
+<p><strong>Примечание:</strong> Возможно, у вас может быть собственная версия игрового примера, которая не работает, которую вы можете исправить! Мы по-прежнему хотели бы, чтобы вы работали над статьей с нашей версией, чтобы вы могли изучать методы, которые мы здесь преподаем. Затем вы можете вернуться и попытаться исправить ваш пример.</p>
+</div>
+
+<p>На этом этапе давайте рассмотрим консоль разработчика, чтобы увидеть, можем ли мы видеть какие-либо синтаксические ошибки, а затем попытаемся их исправить. Вы узнаете, как это сделать, ниже.</p>
+
+<h2 id="Исправление_синтаксических_ошибок">Исправление синтаксических ошибок</h2>
+
+<p>Раньше в курсе мы заставили вас набрать некоторые простые команды JavaScript в <a href="/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools">консоль разработчика JavaScript</a> (если вы не можете вспомнить, как открыть это в своем браузере, следуйте предыдущей ссылке, чтобы узнать, как это сделать). Что еще более полезно, так это то, что консоль предоставляет вам сообщения об ошибках всякий раз, когда существует синтаксическая ошибка внутри JavaScript, которая подается в механизм JavaScript браузера. Теперь пойдем на охоту.</p>
+
+<ol>
+ <li>Перейдите на вкладку, в которой у вас есть number-game-errors.html, и откройте консоль JavaScript. Вы должны увидеть сообщение об ошибке в следующих строках: <img alt="" src="https://mdn.mozillademos.org/files/13496/not-a-function.png" style="display: block; margin: 0 auto;"></li>
+ <li>Это довольно простая ошибка для отслеживания, и браузер дает вам несколько полезных бит информации, которые помогут вам (скриншот выше от Firefox, но другие браузеры предоставляют аналогичную информацию). Слева направо, у нас есть:
+ <ul>
+ <li>Красный «x» означает, что это ошибка.</li>
+ <li>Сообщение об ошибке, указывающее, что пошло не так: «TypeError: guessSubmit.addeventListener не является функцией»</li>
+ <li>Ссылка «Узнать больше», которая ссылается на страницу MDN, которая объясняет, что эта ошибка означает в огромных количествах деталей.</li>
+ <li>Имя файла JavaScript, который ссылается на вкладку «Отладчик» консоли разработчика. Если вы перейдете по этой ссылке, вы увидите точную строку, где подсвечивается ошибка.</li>
+ <li>Номер строки, в которой находится ошибка, и номер символа в этой строке, где первая ошибка. В этом случае у нас есть строка 86, символ номер 3.</li>
+ </ul>
+ </li>
+ <li>Если мы посмотрим на строку 86 в нашем редакторе кода, мы найдем эту строку:
+ <pre class="brush: js"><font><font>guessSubmit.addeventListener('click', checkGuess);</font></font></pre>
+ </li>
+ <li>В сообщении об ошибке говорится, что «guessSubmit.addeventListener не является функцией», поэтому мы, вероятно, где-то ошиблись. Если вы не уверены в правильности написания синтаксиса, часто бывает полезно найти функцию на MDN. Лучший способ сделать это в настоящее время — поиск «mdn <em>имя-функции</em>» в вашей любимой поисковой системе. Вот ссылка, которая поможет сократить вам некоторое время в данном случае: <code><a href="/en-US/docs/Web/API/EventTarget/addEventListener">addEventListener()</a></code>.</li>
+ <li>Итак, глядя на эту страницу, кажется, что ошибка в том, что мы неправильно назвали имя функции! Помните, что JavaScript чувствителен к регистру, поэтому любые незначительные отличия в орфографии или регистре текста могут вызвать ошибку. Изменение этого параметра в addEventListener должно быть исправлено. Сделайте это сейчас.</li>
+</ol>
+
+<div class="note">
+<p><strong>Примечание: </strong>См. наш <a href="/en-US/docs/Web/JavaScript/Reference/Errors/Not_a_function">TypeError: «x»</a> не является справочной страницей функций для получения дополнительной информации об этой ошибке.</p>
+</div>
+
+<h3 id="Синтаксические_ошибки_второй_раунд">Синтаксические ошибки: второй раунд</h3>
+
+<div class="note">
+<p><strong>Примечание</strong>: <code><a href="/en-US/docs/Web/API/Console/log">console.log()</a></code> это часто используемая функция отладки, которая выводит значение в консоль. Поэтому она будет выводить значение <code>lowOrHi</code> в консоли, как только мы попытаемся установить его в строке 48.</p>
+</div>
+
+<ol>
+ <li>Сохраните и обновите страницу, и вы увидите, что ошибка исчезла.</li>
+ <li>Теперь, если вы попробуете ввести значение и нажать кнопку "Submit guess", вы увидите ... другую ошибку!  <img alt="" src="https://mdn.mozillademos.org/files/13498/variable-is-null.png" style="display: block; margin: 0 auto;"></li>
+ <li>На этот раз сообщается об ошибке: "TypeError: lowOrHi is null", в строке 78.
+ <div class="note"><strong>Примечание</strong>: <code><a href="/en-US/docs/Glossary/Null">Null</a></code> — это специальное значение, которое означает "ничего" или "не значение". Поэтому <code>lowOrHi</code> был объявлен и инициализирован без значения — у него нет типа или значения.</div>
+
+ <div class="note"><strong>Примечание</strong>: Эта ошибка не появилась, как только страница была загружена, потому что эта ошибка произошла внутри функции (внутри <code>checkGuess() { ... }</code> block). Об этом вы узнаете более подробно в нашей более поздней статье о функциях, код внутри функций выполняется в отдельной области для кода внешних функций. В этом случае код не был запущен, и ошибка не была брошена до тех пор, пока функция <code>checkGuess()</code> не была запущена строкой 86.</div>
+ </li>
+ <li>Посмотрите на строку 78, и вы увидите следующий код:
+ <pre class="brush: js"><font><font>lowOrHi.textContent = «Последнее предположение было слишком высоко!»;</font></font></pre>
+ </li>
+ <li>Эта строка пытается установить свойство <code>textContent</code> переменной <code>lowOrHi</code> как текстовую строку, но это не работает, поскольку <code>lowOrHi</code> не содержит того, что должна. Давайте посмотрим, почему так происходит — попробуйте найти другие экземпляры <code>lowOrHi</code> в коде. Самый ранний экземпляр, который вы найдете в JavaScript, находится в строке 48:
+ <pre class="brush: js"><font><font>var lowOrHi = document.querySelector('lowOrHi');</font></font></pre>
+ </li>
+ <li>На этом этапе мы пытаемся заставить переменную содержать ссылку на элемент документа HTML. Давайте проверим, является ли значение  <code>null</code> после выполнения этой строки. Добавьте следующий код в строку 49:
+ <pre class="brush: js">console.log(lowOrHi);
+</pre>
+ </li>
+ <li>Сохраните и обновите, и вы должны увидеть результат работы <code>console.log()</code> в консоли браузера. <img alt="" src="https://mdn.mozillademos.org/files/13494/console-log-output.png" style="display: block; margin: 0 auto;"> Разумеется, значение <code>lowOrHi</code> на данный момент равно <code>null</code>, поэтому определенно существует проблема в строке 48.</li>
+ <li>Давайте подумаем о том, что может быть проблемой. Строка 48 использует метод <code><a href="/en-US/docs/Web/API/Document/querySelector">document.querySelector()</a></code> для получения ссылки на элемент, выбирая его с помощью селектора CSS. Посмотрев далее наш файл, мы можем найти обсуждаемый элемент <code>&lt;p&gt;</code>:
+ <pre class="brush: js">&lt;p class="lowOrHi"&gt;&lt;/p&gt;
+</pre>
+ </li>
+ <li>Поэтому нам нужен селектор классов, который начинается с точки (.), но селектор, передаваемый в метод <code>querySelector()</code> в строке 48, не имеет точки. Возможно, это и есть проблема! Попробуйте изменить <code>lowOrHi</code> на <code>.lowOrHi</code> в строке 48.</li>
+ <li>Повторите попытку сохранения и обновления, и ваш вызов <code>console.log()</code> должен вернуть элемент <code>&lt;p&gt;</code>, который мы хотим. Уф! Еще одна ошибка исправлена! Вы можете удалить строку с  <code>console.log()</code> сейчас, или оставить для дальнейшего применения — выбирайте сами.</li>
+</ol>
+
+<div class="note">
+<p><strong>Примечание</strong>: Загляните на справочную страницу <a href="/en-US/docs/Web/JavaScript/Reference/Errors/Unexpected_type">TypeError: "x" is (not) "y"</a>, чтобы узнать больше об этой ошибке.</p>
+</div>
+
+<h3 id="Синтаксические_ошибки_третий_раунд">Синтаксические ошибки: третий раунд</h3>
+
+<ol>
+ <li>Теперь, если вы снова попробуете сыграть в игру, вы должны добиться большего успеха — игра должна играть абсолютно нормально, пока вы не закончите игру, либо угадав нужное число, либо потеряв жизни.</li>
+ <li>На данном этапе игра снова слетает, и выводится такая же ошибка, как и в начале — "TypeError: resetButton.addeventListener is not a function"! Однако, теперь она происходит из-за строки 94.</li>
+ <li>Посмотрев на строку 94, легко видеть, что здесь сделана такая же ошибка. Нам просто нужно изменить <code>addeventListener</code> на <code>addEventListener</code>.</li>
+</ol>
+
+<h2 id="Логическая_ошибка">Логическая ошибка</h2>
+
+<p>На этом этапе игра должна проходить отлично, однако, поиграв несколько раз, вы, несомненно заметите, что случайное число, которое вы должны угадать, всегда 0 или 1. Определенно не совсем так, как мы хотим, чтобы игра была разыграна!</p>
+
+<p>Безусловно, где-то в игре есть логическая ошибка — игра не возвращает ошибку, она просто работает неправильно.</p>
+
+<ol>
+ <li>Найдем переменную <code>randomNumber</code> , и строку где в первый раз устанавливали случайное число. Пример, в котором мы храним случайное число, которое должны угадать, на строке 44:
+
+ <pre class="brush: js">var randomNumber = Math.floor(Math.random()) + 1;
+</pre>
+ И на строке 113, где мы генерируем случайное число, каждый раз после окончания игры:
+
+ <pre class="brush: js">randomNumber = Math.floor(Math.random()) + 1;
+</pre>
+ </li>
+ <li>Чтобы проверить, действительно ли проблема в этом, давайте обратимся к нашему другу <code>console.log()</code> снова — вставьте ее ниже строк с ошибками:
+ <pre class="brush: js">console.log(randomNumber);
+</pre>
+ </li>
+ <li>Сохраните и обновите, а дальше попробуйте пару раз сыграть — в консоли вы увидите что <code>randomNumber</code> равна 1 в каждой точке, где вы ее записали после строк с ошибками.</li>
+</ol>
+
+<h3 id="Работаем_через_логику">Работаем через логику</h3>
+
+<p>Чтобы исправить это, давайте рассмотрим как работает строка. Первое, мы вызываем <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random">Math.random()</a></code>, котрый генерирует случайное десятичное число, между 0 и 1, например 0.5675493843.</p>
+
+<pre class="brush: js"><font><font>Math.random()</font></font></pre>
+
+<p>Дальше, мы передаем результат вызова <code>Math.random()</code> через <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor">Math.floor()</a></code>, который округляет число вниз, до ближайшего целого числа. Затем мы добавляем 1 к данному результату:</p>
+
+<pre><font><font>Math.floor(Math.random()) + 1;</font></font></pre>
+
+<p>Округление случайного десятичного числа к меньшему, всегда будет возвращать 0, так что добавление к нему единицы будет возвращать всегда 1.  Нам нужно умножить случайное число на 100, прежде чем мы округлим его к меньшему. Следующая строка вернет нам случайное число между 0 и 99:</p>
+
+<pre class="brush: js"><font><font>Math.floor(Math.random() * 100);</font></font></pre>
+
+<p>поэтому нам нужно добавить 1, чтоб нам возвращалось случайное число между 1 и 100:</p>
+
+<pre class="brush: js"><font><font>Math.floor(Math.random() * 100) + 1;</font></font></pre>
+
+<p>А теперь, исправьте обе строки с ошибками, затем сохраните и обновите, игра должна работать так, как мы и планировали!</p>
+
+<h2 id="Другие_распространенные_ошибки">Другие распространенные ошибки</h2>
+
+<p>Существуют и другие распространенные ошибки, которые вы обнаружите в своем коде. В этом разделе показано большинство из них.</p>
+
+<h3 id="SyntaxError_отсутствует_перед_постановкой"><font><font>SyntaxError: отсутствует ; </font><font>перед постановкой</font></font></h3>
+
+<p>Эта ошибка обычно означает что вы упустили точку с запятой в конце одной из ваших строк кода, но иногда ошибка может быть более загадочной. Например, если мы изменим эту строку внутри функции <code>checkGuess()</code> :</p>
+
+<pre class="brush: js"><font><font>var userGuess = Number(guessField.value);</font></font></pre>
+
+<p>на эту</p>
+
+<pre class="brush: js"><font><font>var userGuess === Number(guessField.value);</font></font></pre>
+
+<p>Это вызовет данную ошибку, потому что браузер подумает, что вы пытались сделать что-то другое. Вы должны быть уверены, что вы не перепутали оператор присваивания (<code>=</code>), который присваивает значение переменной — с оператором сравнения (<code>===</code>), который строго сравнивает операнды, и возвращает <code>true</code>/<code>false</code> .</p>
+
+<div class="note">
+<p><strong>Примечание</strong>: Загляните на справочную страницу <a href="/ru/docs/Web/JavaScript/Reference/Errors/Missing_semicolon_before_statement">Синтаксическая ошибка: пропущен символ ; до объявления инструкции</a> для получения дополнительной информации об этой ошибке.</p>
+</div>
+
+<h3 id="В_программе_всегда_говорится_что_вы_выиграли_независимо_от_того_что_вы_ввели">В программе всегда говорится, что вы выиграли, независимо от того, что вы ввели</h3>
+
+<p>Причиной этому является все то же перепутывание оператора присваивания (<code>=</code>) со строгим сравнением (<code>===</code>). Например, если мы изменим внутри <code>checkGuess()</code> эту строку кода:</p>
+
+<pre class="brush: js"><font><font>if (userGuess === randomNumber) {</font></font></pre>
+
+<p>на эту</p>
+
+<pre class="brush: js"><font><font>if (userGuess = randomNumber) {</font></font></pre>
+
+<p>мы всегда будем получать <code>true</code>, заставляя программу сообщать, что игра была выиграна. Будьте осторожны!</p>
+
+<h3 id="SyntaxError_отсутствует_после_списка_аргументов"><font><font>SyntaxError: отсутствует ) после списка аргументов</font></font></h3>
+
+<p>Эта ошибка проста — обычно она означает, что вы пропустили закрывающую скобку с конца вызова функции / метода.</p>
+
+<div class="note">
+<p><strong>Примечание</strong>: Загляните на справочную страницу  <a href="/en-US/docs/Web/JavaScript/Reference/Errors/Missing_parenthesis_after_argument_list">SyntaxError: missing ) after argument list</a> для получения дополнительной информации об этой ошибке.</p>
+</div>
+
+<h3 id="SyntaxError_missing_after_property_id">SyntaxError: missing : after property id</h3>
+
+<p dir="ltr">Эта ошибка обычно связана с неправильно сформированным объектом JavaScript, но в этом случае нам удалось получить ее, изменив</p>
+
+<pre class="brush: js"><font><font>function checkGuess() {</font></font></pre>
+
+<p>на</p>
+
+<pre class="brush: js"><font><font>function checkGuess( {
+</font></font></pre>
+
+<p dir="ltr" id="tw-target-text">Это заставило браузер думать, что мы пытаемся передать содержимое функции в функцию в качестве аргумента. Будьте осторожны с этими скобками!</p>
+
+<h3 id="SyntaxError_missing_after_function_body">SyntaxError: missing } after function body</h3>
+
+<p>Это легко — обычно это означает, что вы пропустили одну из ваших фигурных скобок из функции или условной структуры. Мы получили эту ошибку, удалив одну из закрывающих фигурных скобок возле нижней части функции  <code>checkGuess()</code>.</p>
+
+<h3 id="SyntaxError_expected_expression_got_string_or_SyntaxError_unterminated_string_literal">SyntaxError: expected expression, got '<em>string</em>' or SyntaxError: unterminated string literal</h3>
+
+<p><font><font>Эти ошибки обычно означает, что вы пропустили открывающую или закрывающую кавычку для строковых значений. </font><font>В первой ошибки выше,  </font></font><em><font><font>строка</font></font></em><font><font>  будет заменена на неожиданный персонаж (ей) , </font><font>что браузер нашел вместо кавычек в начале строки. </font><font>Вторая ошибка означает , </font><font>что строка не закончилась кавычки.</font></font></p>
+
+<p>При всех этих ошибках действуйте так, как в наших  примерах, которые мы рассмотрели в пошаговом руководстве. Когда возникает ошибка, посмотрите полученный номер строки, перейдите к этой строке и посмотрите, можете ли вы определить, что случилось. Имейте в виду, что ошибка не обязательно будет на этой строке, а также, что ошибка может быть вызвана не такой же проблемой, которую мы привели выше!</p>
+
+<div class="note">
+<p><strong><font><font>Примечание</font></font></strong><font><font> : Смотрите наш </font></font><a href="/en-US/docs/Web/JavaScript/Reference/Errors/Unexpected_token"><font><font>SyntaxError: Неожиданный токен</font></font></a><font><font> и </font></font><a href="/en-US/docs/Web/JavaScript/Reference/Errors/Unterminated_string_literal"><font><font>SyntaxError: незавершенная строка</font></font></a><font><font> эталонных страниц для получения </font><font>более подробной информации об этих ошибках.</font></font></p>
+</div>
+
+<h2 id="Резюме"><font><font>Резюме</font></font></h2>
+
+<p>Итак, мы научились основам  выяснения ошибок в простых программах JavaScript. Не всегда так просто разобраться, что не так в вашем коде, но, по крайней мере, это сэкономит вам несколько часов сна и позволит вам продвигаться немного быстрее, когда что-либо заработает не так, как ожидалось, в вашем учебном путешествии.</p>
+
+<h2 id="Смотрите_также"><font><font>Смотрите также</font></font></h2>
+
+<div>
+<ul>
+ <li><font><font>Есть много других типов ошибок, которые не перечислены здесь; </font><font>мы составляем ссылку , </font><font>которая объясняет , </font><font>что они означают подробно - см. </font></font><a href="/en-US/docs/Web/JavaScript/Reference/Errors"><font><font>ссылку ошибки JavaScript</font></font></a><font><font> .</font></font></li>
+ <li><font><font>Если вы столкнетесь с любыми ошибками в коде, </font><font>которые вы не знаете , </font><font>как исправить после прочтения этой статьи, вы можете получить помощь! </font><font>Спросите на </font></font><a class="external external-icon" href="https://discourse.mozilla-community.org/t/learning-web-development-marking-guides-and-questions/16294"><font><font>нить обучения Область дискурсе</font></font></a><font><font> , или в </font></font><a href="irc://irc.mozilla.org/mdn"><font><font>#mdn</font></font></a><font><font> IRC канал на </font></font><a class="external external-icon" href="https://wiki.mozilla.org/IRC"><font><font>Mozilla IRC</font></font></a><font><font>. </font><font>Расскажите нам, какая</font><font> у вас ошибка, и мы постараемся вам помочь. </font><font>Приложите пример своего кода для большей ясности проблемы.</font></font></li>
+</ul>
+</div>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Первые_шаги/A_first_splash", "Learn/JavaScript/Первые_шаги/Variables", "Learn/JavaScript/Первые_шаги")}}</p>