{"action":"created","comment":{"url":"https://api.github.com/repos/denysdovhan/understandinges6ua/pulls/comments/62045939","id":62045939,"diff_hunk":"@@ -0,0 +1,1204 @@\n+# Функції\n+\n+Функцій — важлива частина будь–якої мови програмування, і до ECMAScript 6, функції в JavaScript на зазнавали значних змін з моменту створення мови. Це накопичувало проблеми та нюанси поведінки, які призводили до помилкок та потребували більше коду для виконання базових завдань.\n+\n+Функції в ECMAScript 6 зробили великий крок уперед, беручи до уваги скарги та прохання JavaScript–розробників. Результатом стали численні покращення ECMAScript 5 функцій, що допоможуть уникнути помилок при програмуванні на JavaScript та зроблять його більш потужним.\n+\n+## Функції з параметрами за замовчуванням\n+\n+Функції в JavaScript є унікальними з тієї точки зору, що дозволяють приймати будь-яку кількість параметрів, незалежновід того, яку кількість параметрів було оголошено при визначенні функції. Це дозволяє вам визначати функції, що можуть оперувати різною кількістю параметрів просто підставляючи значення за замовчуванням, коли вони не передані. Цей розділ розповідає про те, як параметри за замовчуванням працюють до та в ECMAScript 6, разом з важливою інформацією про об’єкт `arguments`, використання виразів у якості параметрів та інші нюанси.\n+\n+### Імітування параметрів за замовчуванням у ECMAScript 5\n+\n+У ECMAScript 5 та раніше ви, напевно, використовували такий шаблон для створення функції з параметрами за замовчуванням:\n+\n+```js\n+function makeRequest(url, timeout, callback) {\n+\n+    timeout = timeout || 2000;\n+    callback = callback || function() {};\n+\n+    // решта функції\n+\n+}\n+```\n+\n+У цьому прикладі і `timeout`, і `callback` є насправді необов’язковими, тому що їм передаються значення за замовчуваннями, якщо вони не вказані. Логічний оператор AБО (`||`) завжди повертає другий оперант, якщо перший є хибним. Оскільки вказані параметри не вказані, їм буде встановелене значення `undefined`, таким чином оператор логічного АБО часто використовується для встановлення пропущеним параметрам значень за замовчуванням. Однак, у такому підході є недолік: у тому випадку, якщо `timeout` матиме значення `0`, яке є валідним, воно буде замінене на `2000`, тому що `0` є хибою.\n+\n+У цьому випадку, безпечнішою альтернативою первірки чи було передано аргумент є використання `typeof`, як у цьому прикладі:\n+\n+```js\n+function makeRequest(url, timeout, callback) {\n+\n+    timeout = (typeof timeout !== \"undefined\") ? timeout : 2000;\n+    callback = (typeof callback !== \"undefined\") ? callback : function() {};\n+\n+    // решта функції\n+\n+}\n+```\n+\n+Цей підхід безпечніший, але він потребує багато зайвого коду для такої простої операції. Популярні JavaScript–бібліотеки часто використовують подібний патерн, оскільки цей підхід є загальним.\n+\n+### Параметри за замовчуванням у ECMAScript 6\n+\n+ECMAScript 6 полегшує передачу значень параметрам за замовчуванням шляхом ініціалізації, яка відбувається, коли параметер не був переданий. Наприклад:\n+\n+```js\n+function makeRequest(url, timeout = 2000, callback = function() {}) {\n+\n+    // the rest of the function\n+\n+}\n+```\n+\n+Ця функція очікує, що лише перший параметер буде передаватись завжди. Інші два параметри мають значення за замовчуванням, що робить тіло функції меншим, оскільки вам не потрібно писати додатковий код для перевірки значень.\n+\n+Коли `makeRequest()` з усіма трьома параметрами, параметри за замовчуванням не будуть використовуватись. Наприклад:\n+\n+```js\n+// використовує значення timeout та callback за замовчуванням\n+makeRequest(\"/foo\");\n+\n+// використовує callback за замовчуванням\n+makeRequest(\"/foo\", 500);\n+\n+// не використовує значення за замовчуванням\n+makeRequest(\"/foo\", 500, function(body) {\n+    doSomething(body);\n+});\n+```\n+\n+ECMAScript 6 розглядає `url` як обов’язковий параметер, тому ми передаємо `\"/foo\"` у всіх трьох викликах `makeRequest()`. Два параметри зі значеннями за замовчуванням розглядаються як необов’язкові.\n+\n+Можливо задавати значення за замовчуванням для будь–яких аргументів, включаючи ті, які стоять у оголошенні функції перед аргументами без значень за замовчуванням. Наприклад, такий код працює як і очікується:\n+\n+```js\n+function makeRequest(url, timeout = 2000, callback) {\n+\n+    // решта функції\n+\n+}\n+```\n+\n+У цьому випадку значення `timeout` за замовчування використовуватиметься лише тоді, коли другий аргумент не переданий, або якщо в якості другого аргументу безпосередньо передати `undefined`, як у цьому прикладі:\n+\n+```js\n+// використовує timeout за замовчуванням\n+makeRequest(\"/foo\", undefined, function(body) {\n+    doSomething(body);\n+});\n+\n+// використовує значення timeout за замовчуванням\n+makeRequest(\"/foo\");\n+\n+// не використовує значення timeout за замовчуванням\n+makeRequest(\"/foo\", null, function(body) {\n+    doSomething(body);\n+});\n+```\n+\n+У цьому випадку, значення `null` приймається як валідне і означає, що в третьому виклику `makeRequest()` значення `timeout` за замовчуванням не буде використовуватись.\n+\n+### Як параметри за замовчуванням впливають на об’єкт arguments\n+\n+Просто запам’ятайте, що поведніка об’єкту `arguments` відрізняється від звичної, якщо використовуються значення за замовчуванням. У нестрогому режимі (nonstrict mode) ECMAScript 5, об’єкт `arguments` відображає зміни у іменованих параметрах функції. Нижче наведений код, який ілюструє як це працює:\n+\n+```js\n+function mixArgs(first, second) {\n+    console.log(first === arguments[0]);\n+    console.log(second === arguments[1]);\n+    first = \"c\";\n+    second = \"d\";\n+    console.log(first === arguments[0]);\n+    console.log(second === arguments[1]);\n+}\n+\n+mixArgs(\"a\", \"b\");\n+```\n+\n+Вивід:\n+\n+```\n+true\n+true\n+true\n+true\n+```\n+\n+У нестрогому режимі об’єкт `arguments` завжди оновлюється, щоб відображати зміни в іменованих параметрах. Тобто, якщо `first` та `second` присвоїти нові значення, `arguments[0]` там `arguments[1]` оновляться миттєво, так що порівняння `===` даватиме результат `true`.\n+\n+Однак строгий режим (strict mode) ECMAScript 5 усуває цей неочевидну властивість об’єкту `arguments`. У строгому режимі, об’єкт `arguments` не відображає зміни в іменованих параметрах. Нижче знову наведена функція `mixArgs()`, але у строгому режимі:\n+\n+```js\n+function mixArgs(first, second) {\n+    \"use strict\";\n+\n+    console.log(first === arguments[0]);\n+    console.log(second === arguments[1]);\n+    first = \"c\";\n+    second = \"d\"\n+    console.log(first === arguments[0]);\n+    console.log(second === arguments[1]);\n+}\n+\n+mixArgs(\"a\", \"b\");\n+```\n+\n+Виклик `mixArgs()` виведе:\n+\n+```\n+true\n+true\n+false\n+false\n+```\n+\n+Цього разу зміни `first` та `second` не повпливали на `arguments`, тому вивід буде саме таким, яким ви його очікуєте.\n+\n+Об’єкт `arguments` у функціях, що використовують ECMAScript 6 параметри за замовчуванням, однак, завжди поводитимуться так, як вони поводяться у строгому режимі ECMAScript 5, незалежно від того чи функція працює у строгому режимі чи ні. Наявність параметрів за замовчуванням робить об’єкт `arguments` незалежним від іменованих параметрів. Це тонка, але важлива деталь того як об’єкт `arguments` може бути використаний. Розгляньте наступне:\n+\n+```js\n+// не строгий режим\n+function mixArgs(first, second = \"b\") {\n+    console.log(arguments.length);\n+    console.log(first === arguments[0]);\n+    console.log(second === arguments[1]);\n+    first = \"c\";\n+    second = \"d\"\n+    console.log(first === arguments[0]);\n+    console.log(second === arguments[1]);\n+}\n+\n+mixArgs(\"a\");\n+```\n+\n+Виведе:\n+\n+```\n+1\n+true\n+false\n+false\n+false\n+```\n+\n+У цьому прикладі, `arguments.length` рівне 1 тому що лише один аргумент було передано до `mixArgs()`. Це також означає, що `arguments[1]` рівний `undefined`, що є очікованою поведінкою, коли лише один аргумент передається у функцію. Це також означає, що `first` є рівним `arguments[0]`. Зміна `first` та `second` не повпливає на `arguments`. Така поведінка буде у як у строгому так і нестрогому режимах, тож ви можете бути певні, що `arguments` завжди відображатиме початковий стан виклику.\n+\n+### Вирази в параметрах за замовчуванням\n+\n+Одним з найбільш цікавих нововведень параметрів за замовчуванням є те, що їх значення не обов’язково мають бути примітивними значеннями. Ви можете, до прикладу, викликати функцію, що повертатиме значення параметру, ось так:\n+\n+```js\n+function getValue() {\n+    return 5;\n+}\n+\n+function add(first, second = getValue()) {\n+    return first + second;\n+}\n+\n+console.log(add(1, 1));     // 2\n+console.log(add(1));        // 6\n+```\n+\n+Тут, якщо останній аргумент не переданий, викликається фукнція `getValue()`, що повертає коректне значення за замовчуванням. Пам’ятайте, що `getValue()` буде викликана лише тоді, коли `add()` буде викликана без другого аргументу, а не тоді, коли оголошення функції буде оброблене інтерпретатором. Це означає, що якщо `getValue()` була написана змінною, вона буде повертати різні значення. Для розуміння:\n+\n+```js\n+let value = 5;\n+\n+function getValue() {\n+    return value++;\n+}\n+\n+function add(first, second = getValue()) {\n+    return first + second;\n+}\n+\n+console.log(add(1, 1));     // 2\n+console.log(add(1));        // 6\n+console.log(add(1));        // 7\n+```\n+\n+У цьому прикладі, `value` має значення п’ять і збільшується на одиницю щоразу, коли викликається `getValue()`. Перший виклик `add(1)` повертає 6, тоді другий виклик `add(1)` повертає 7, тому що `value` був збільшений на одиницю. Оскільки значення `second` за замовчуванням обчислюється при виклику функції, можна змінюти це значення у будь–який час.\n+\n+W> Будьте обережними при використанні виклику фукнцій в якості параметрів за замовчуванням. Якщо ви забудете дужки, як ось `second = getValue` у останньому прикладі, ви отримаєте посилання на функцію замість результату її виклику.\n+\n+Така поведінка демонструє іншу цікаву особливість. Ви можете використовувати параметер за замовчування для наступного параметра. Ось приклад:\n+\n+```js\n+function add(first, second = first) {\n+    return first + second;\n+}\n+\n+console.log(add(1, 1));     // 2\n+console.log(add(1));        // 2\n+```\n+\n+У цьому прикладі, параметр `second` отримує значення `first` за замовчуванням, що означає, що виклик фукнції з одним аргументом присвоїть обом параметрам однакове значення. Тому `add(1, 1)` поверне 2, так само як `add(1)` повертає 2. Навіть більше, ви можете передати `first` у функцію, щоб отримаи значення `second` ось так:\n+\n+```js\n+function getValue(value) {\n+    return value + 5;\n+}\n+\n+function add(first, second = getValue(first)) {\n+    return first + second;\n+}\n+\n+console.log(add(1, 1));     // 2\n+console.log(add(1));        // 7\n+```\n+\n+Цей приклад встановлює `second` рівним значенню, яке було повернуте `getValue(first)`, тому `add(1, 1)` продовжує повертати 2, а `add(1)` поверне 7 (1 + 6).\n+\n+Можливість посилатись на параметри працює лише при зверненні до попередніх аргументів, тому аргументи попереду не мають доступу до наступних аргументів. Наприклад:\n+\n+```js\n+function add(first = second, second) {\n+    return first + second;\n+}\n+\n+console.log(add(1, 1));     // 2\n+console.log(add(1));        // викине помилку\n+```\n+\n+Виклик `add(1)` викине помилку, тому що `second` визначений після `first` і тому недоступний в якості значення за замовчуванням. Щоб зрозуміти що тут відбувається, важливо згадати що таке тимчасом мертва зона.\n+\n+### Тимчасова мертва зона параметрів за замовчуванням\n+\n+Глава 1 ввела поняття тимчасової мертвої зони (ТМЗ) яка стосувалась `let` та `const`, втім параметри за замовчуванням також мають ТМЗ, з якої параметри будуть недоступними. Подібно до `let`–оголошення, кожен параметр створює новий ідентифікатор зв’язування, на який не можна посилатись до його ініціалізації не спричинивши помилки. Ініціалізація параметрів відбувається тоді, коли функція викликається, \n+Parameter initialization happens when the function is called, або при передачі параметрам значення, або при використанні значень параметрів за замовчуванням.\n+\n+Щоб дослідити ТМЗ параметрів за замовчуванням, розглянемо цей приклад з розділу «Вирази в параметрах за замовчуванням»:\n+\n+```js\n+function getValue(value) {\n+    return value + 5;\n+}\n+\n+function add(first, second = getValue(first)) {\n+    return first + second;\n+}\n+\n+console.log(add(1, 1));     // 2\n+console.log(add(1));        // 7\n+```\n+\n+Виклики `add(1, 1)` та `add(1)` ефективно виконують присвоєння `first` та `second` значень за замовчуванням:\n+\n+```js\n+// JavaScript представлення виклику add(1, 1)\n+let first = 1;\n+let second = 1;\n+\n+// JavaScript представлення виклику add(1)\n+let first = 1;\n+let second = getValue(first);\n+```\n+\n+Коли функція `add()` виконується вперше, зв’язування `first` та `second` додаються до специфічної для параметрів ТМЗ (схоже на те, як поводить себе `let`). Тому `second` може бути ініціалізований зі значенням `first`, оскільки `first` у той момент буде вже ініціалізованим, але протилежне не є вірним. Тепер розглянемо змінену функцію `add()`:\n+\n+```js\n+function add(first = second, second) {\n+    return first + second;\n+}\n+\n+console.log(add(1, 1));         // 2\n+console.log(add(undefined, 1)); // кидає помилку\n+```\n+\n+Давайте розглянемо, що відбувається за лаштунками при виклику `add(1, 1)` та `add(undefined, 1)` у цьому прикладі:\n+\n+```js\n+// JavaScript представлення виклику add(1, 1)\n+let first = 1;\n+let second = 1;\n+\n+// JavaScript представлення виклику add(undefined, 1)\n+let first = second;\n+let second = 1;\n+```\n+\n+У цьому випадку, виклик `add(undefined, 1)` призводить до помилки, тому що `second` ще не був ініціалізований тоді, коли ініціалізується `first`. У цьому випадку, `second` знаходиться у ТМЗ і тому будь–яке посилання на нього призведе до помилки. Схожу поведінку `let`–оголошень було розглянуто у Главі 1.\n+\n+I> Параметри функцій мають власну області видимості та власні ТМЗ, що відрізняються від області видимості функцій. Це означає, що значення параметрів за замовчуванням не можуть звертатись до будь–якої змінної, оголошеної всередині тіла функції.\n+\n+## Робота з неіменованими параметрами\n+\n+До цих пір, приклади у цій главі були пов’язані лише з параметри, які мали імена у виразі функції. Однак, функції JavaScript не обмежують кількість параметрів, які ми можемо передавати у функцію, кількістю параметрів, які вказані при заданні функції. Ви завжди можете передати менше або більше параметрів, ніж формально оголошено. Значення за замовчування допомагають тоді, коли функція може приймати менше параметрів, але ECMAScript 6 також пропонує вирішення проблеми з передачею більшої кількості параметрів, ніж вказано в оголошенні.\n+\n+### Неіменовані параметри в ECMAScript 5\n+\n+Раніше JavaScript пропонував об’єкт `arguments` для того, щоб працювати з усіма параметрами, які були передані у функцію, без необхдіності вказувати кожен параметер індивідуально. Об’єкт `arguments` чудово працює у більшості випадків, проте цей об’єкт може бути занадто громіздким. Наприклад, дослідіть цей код, який оперує об’єктом `arguments`:\n+\n+```js\n+function pick(object) {\n+    let result = Object.create(null);\n+\n+    // починаючи з другого параметра\n+    for (let i = 1, len = arguments.length; i < len; i++) {\n+        result[arguments[i]] = object[arguments[i]];\n+    }\n+\n+    return result;\n+}\n+\n+let book = {\n+    title: \"Understanding ECMAScript 6\",\n+    author: \"Nicholas C. Zakas\",\n+    year: 2015\n+};\n+\n+let bookData = pick(book, \"author\", \"year\");\n+\n+console.log(bookData.author);   // \"Nicholas C. Zakas\"\n+console.log(bookData.year);     // 2015\n+```\n+\n+Ця фукнція відтворює метод `pick()` з бібліотеки *Underscore.js*, який повертає копію даного об’єкту з деякою підмножиною властивостей оригінального об’єкту. У цьому прикладі оголошується лише один аргумент і очікується, що він буде об’єктом з якого будуть копіюватись властивості. Усі інші аргументи, які передаються — це імена властивостей, які мають бути копійованими до результату.\n+\n+Є кілька речей, які потрібно зауважити у функції `pick()`. По–перше, не зовсім очевидно, що функція може обробляти біліше одного параметра. Ви могли би задати більше параметрів, але було би не достатньо очевидно, що фукнція може приймати будь–яку кількість параметрів. По–друге, оскільки перший параметр іменований та використовується безпосередньо, якщо ви звернете увагу на властивості, які мають бути скопійовані, то муситиме звертатись до об’єкту `arguments` починаючи з індексу 1 замість індексу 0. Запам’ятовування відповідних індексів для `arguments` не є складним, проте це ще одна річ, за якою потрібно стежити.\n+\n+ECMAScript 6 вводить залишкові (rest) параметри, щоб вирішити цю проблему.\n+\n+### Залишкові (rest) параметри\n+\n+*Залишкові параметри* (або *rest–параметри*) позначаються трьома крапками (`...`) перед іменованим параметром. Цей іменований параметр стає масивом (`Array`), що містить решту параметрів, які були передані функції. Наприклад, `pick()` можна переписати з використанням залишкових параметрів ось так:\n+\n+```js\n+function pick(object, ...keys) {\n+    let result = Object.create(null);\n+\n+    for (let i = 0, len = keys.length; i < len; i++) {\n+        result[keys[i]] = object[keys[i]];\n+    }\n+\n+    return result;\n+}\n+```\n+\n+У цій версії функції, `keys` це залишковий параметр, який містить всі параметри, передані після `object` (на відміну від `arguments`, який містить всі параметри, включаючи перший). Це означає, що ви без проблем можете ітеруватись по `keys` від початку і до кінця. В якості бонусу, ви можете з першого погляду бачити, що функція працює з будь–якою кількістю параметрів.\n+\n+I> Залишкові параметри не впливають на властивість функції `length`, яка вказує на кількість іменованих параметрів функції. Значення `length` для `pick()` у цьому прикладі є рівним 1, оскільки буде враховутись лише `object`.\n+\n+#### Обмеження залишкових параметрів\n+\n+Є два обмеження пов’язані з залишковими параметрами. Перше обмеження: може бути лише один залишковий параметр і він має бути останнім. Для прикладу, такий код не працюватиме.\n+\n+```js\n+// Syntax error: Can't have a named parameter after rest parameters\n+function pick(object, ...keys, last) {\n+    let result = Object.create(null);\n+\n+    for (let i = 0, len = keys.length; i < len; i++) {\n+        result[keys[i]] = object[keys[i]];\n+    }\n+\n+    return result;\n+}\n+```\n+\n+Тут, праметр `last` слідує за залишковим параметром `keys`, що спричинило би синтактичну помилку.\n+\n+Друге обмеження це те, що залишковий параметр не може використовуватись у сетерах об’єктних літералів. Це означає, що такий код також призведе до помилки:\n+\n+```js\n+let object = {\n+\n+    // Syntax error: Can't use rest param in setter\n+    set name(...value) {\n+        // якийсь код\n+    }\n+};\n+```\n+\n+Це обмеження має місце тому, що сетери об’єктних літералів обмежуються одним аргументом. Залишкові параметри, за визначенням, є нескінченною кількістю аргументів, тож вони не дозволені у цьому контексті.\n+\n+#### Як залишкові параметри впливають на об’єкт arguments\n+\n+Залишкові параметри покликані замінити `arguments` в ECMAScript. Спочатку, ECMAScript 4 покінчив з `arguments` та включав залишкові параметри, які дозволяли би передавати необмежену кількість аргументів у функцію. ECMAScript 4 не був прийнятим, але ця ідея була збережена та відтворена у ECMAScript 6, не зважаючи на те, що `arguments` не був видалений з мови.\n+\n+Об’єкт `arguments` працює разом із залишковими параметрами відображаючи аргументи, які були передані до функції при виклику. Це ілюструє така програма:\n+\n+```js\n+function checkArgs(...args) {\n+    console.log(args.length);\n+    console.log(arguments.length);\n+    console.log(args[0], arguments[0]);\n+    console.log(args[1], arguments[1]);\n+}\n+\n+checkArgs(\"a\", \"b\");\n+```\n+\n+Виклик `checkArgs()` виведе:\n+\n+```\n+2\n+2\n+a a\n+b b\n+```\n+\n+Об’єкт `arguments` завжди коректно відображає параметри, що були передані до функції незалежно від використання залишкових параметрів.\n+\n+Це все, що вам потрібно знати про залишкові параметри, щоб почати використовувати їх. Наступний розділ продовжить розповідь про оператор розкладу (spread), який є дуже схожим на залишкові параметри.\n+\n+## Розширені можливості конструктора Function\n+\n+Конструктор `Function` є рідковикористовуваною частиною JavaScript, яка дозволяє вам динамічно створювати нові функції. Аргументами контруктора є параметри для функції та тіло функції, всі аргументи у вигляді рядків. Ось приклад:\n+\n+```js\n+var add = new Function(\"first\", \"second\", \"return first + second\");\n+\n+console.log(add(1, 1));     // 2\n+```\n+\n+ECMAScript 6 доповнює `Function` можливостями задання параметрів за замовчуванням та залишкових параметрів. Вам потрібно лише додати знак рівності між значенням та ім’ям параметра:\n+\n+```js\n+var add = new Function(\"first\", \"second = first\",\n+        \"return first + second\");\n+\n+console.log(add(1, 1));     // 2\n+console.log(add(1));        // 2\n+```\n+\n+У цьому прикладі параметр `second` присвоюється значення `first`, коли переданий лише один параметр. Синтаксис такий же як і для функцій, що не використовують `Function`.\n+\n+Для залишкових параметрів, просто додайте `...` перед останнім параметром, як тут:\n+\n+```js\n+var pickFirst = new Function(\"...args\", \"return args[0]\");\n+\n+console.log(pickFirst(1, 2));   // 1\n+```\n+\n+Цей код створює функцію, яка використовує лише один залишковий параметр та повертає перший аргумент, який був переданий у функцію.\n+\n+Доповнення параметрами за замовчуванням та залишковими параметрами прирівнює можливості `Function` до можливостей декларативних форм оголошення функцій.\n+\n+## Оператор розкладу (spread)\n+\n+Близьким до залишкових параметрів є оператор розкладу (spread). Залишкові параметри дозволяють вам вказати як кілька незалежних аргументів можуть комбінуватись у масив, тоді як оператор розкладу дозволяє вам задати як масив має розкласти свої елементи у окремі аргументи функції. Розгляньте метод `Math.max()`, який приймає будь–яку кількість аргументів та повертає найбільше значення. Ось приклад використання цього методу:\n+\n+```js\n+let value1 = 25,\n+    value2 = 50;\n+\n+console.log(Math.max(value1, value2));      // 50\n+```\n+\n+Коли ви працюєте з двома значеннями, як у цьому прикладі, `Math.max()` використовувати легко. Два значення передаються і повертається найбільше. Але що якщо ви працюєте з значеннями масиву і вам потрібно знайти найбільше значення? Метод `Math.max()` не дозволяє вам передавати масив, тому в ECMAScript 5 та раніше ви би застрягли шукаючи значення самостійно, або використовували б `apply()` як ось тут:\n+\n+```js\n+let values = [25, 50, 75, 100]\n+\n+console.log(Math.max.apply(Math, values));  // 100\n+```\n+\n+Це рішення працює, але використання `apply()` в такому вигляді вносить деяку плутанину. Це виглядає наче навмисне заплутування коду додатковим синтаксисом.\n+\n+Оператор розкладу ECMAScript 6 вирішує цю проблему дуже легко. Замість виклику `apply()`, ви можете передати масив у `Math.max()` на пряму, додавши попереду `...`, як і у випадку з залишковими параметрами. Рушій JavaScript розкладе масив у окремі аргументи та передасть їх у функцію, ось так:\n+\n+```js\n+let values = [25, 50, 75, 100]\n+\n+// еквівалент для\n+// console.log(Math.max(25, 50, 75, 100));\n+console.log(Math.max(...values));           // 100\n+```\n+\n+Тепер виклик `Math.max()` виглядає більш звично та уникає складності, пов’язаної з заданням `this`–зв’язування (першого аргументу `Math.max.apply()` у попередньому прикладі) для простої математичної операції.\n+\n+Ви можете змішувати та комбінувати оператор розкладу з іншими аргументами. Припустимо вам потрібно, щоб найменшим числом, яке поверне `Math.max()` був 0 (просто для випадку, якщо якесь число менше 0 закрадеться у масив). Ви можете передати аргумент окремо та продовжувати використовувати оператор розкладу для інших аргументів:\n+\n+```js\n+let values = [-25, -50, -75, -100]\n+\n+console.log(Math.max(...values, 0));        // 0\n+```\n+\n+У цьому прикладі, останній аргумент, переданий до `Math.max()` буде `0`, який був переданий після всіх інших аргументів переданих з використанням оператору розкладу.\n+\n+Оператор розкладу для передачі аргументів робить використання масивів у функцях набагато легшим. Ви знайдете зручну заміну для методу `apply()` у більшості випадках.\n+\n+На додачу до прикладів використання залишкових та параметрів за замовчуванням, в ECMAScript 6, ви можете також використовувати обидва типи у JavaScript–конструкторі  `Function`.\n+\n+## Властивість name в ECMAScript 6\n+\n+Ідентифікування функцій в JavaScript може виявитись складним завданням, зважаючи на численні способи визначення функцій. Крім того, поширення анонімних функцій робить відлагоджування набагато складнішим, адже стек викликів є складним для розуміння. Виходячи з цих міркувань, ECMAScript 6 вводить властивість `name` для всіх функцій.\n+\n+### Вибір відповідного імені\n+\n+Всі функції в програмах на ECMAScript 6 будуть мати відповідні значення властивості `name`. Щоб побачити це в дії, погляньте на приклад нижче, який демонструє фукнцію і функціональний вираз та виводить властивість `name` для обох:\n+\n+```js\n+function doSomething() {\n+    // ...\n+}\n+\n+var doAnotherThing = function() {\n+    // ...\n+};\n+\n+console.log(doSomething.name);          // \"doSomething\"\n+console.log(doAnotherThing.name);       // \"doAnotherThing\"\n+```\n+\n+У цьому коді, `doSomething()` має властивість `name`, що рівна `\"doSomething\"`, оскільки це оголошення функції. Вираз з анонімною функцією `doAnotherThing()` має `name` рівне `\"doAnotherThing\"`, тому що таке ім’я змінної, якій він був присвоєний.\n+\n+### Особливі випадки властивості name\n+\n+Відповідні імена для оголошень фукнцій та функціональних виразів знайти легко, але ECMAScript 6 іде далі, щоб впевнетись, що *всі* функції мають відповідні імена. Щоб зрозуміти це, розгляньте наступний приклад:\n+\n+```js\n+var doSomething = function doSomethingElse() {\n+    // ...\n+};\n+\n+var person = {\n+    get firstName() {\n+        return \"Nicholas\"\n+    },\n+    sayName: function() {\n+        console.log(this.name);\n+    }\n+}\n+\n+console.log(doSomething.name);      // \"doSomethingElse\"\n+console.log(person.sayName.name);   // \"sayName\"\n+console.log(person.firstName.name); // \"get firstName\"\n+```\n+\n+У цьому прикладі,`doSomething.name` є `\"doSomethingElse\"` оскільки функціональний вираз має власне ім’я, яке має пріорітет над змінною, якій ця функція була присвоєна. Властивість `name` у `person.sayName()` рівна `\"sayName\"`, бо це значення було інтерпретоване з об’єктного літералу. Так само, `person.firstName` насправді є функцією–гетером, тож її ім’я `\"get firstName\"`, що вказує на цю відмінність. Функції–сетери так само позначаються через `\"set\"`.\n+\n+Також є кілька інших особливих випадків для імен функцій. Функції, створені з використанням `bind()` будуть мати імена з префіксованим `\"bound\"`, а функції створені конструктором `Function` мають ім’я `\"anonymous\"`:\n+\n+```js\n+var doSomething = function() {\n+    // ...\n+};\n+\n+console.log(doSomething.bind().name);   // \"bound doSomething\"\n+\n+console.log((new Function()).name);     // \"anonymous\"\n+```\n+\n+`name` зв’язаної функції буде завжди `name` функції, що була зв’язана з префіксом `\"bound \"`, тому зв’язана версію `doSomething()` буде `\"bound doSomething\"`.\n+\n+Запам’ятайте, що значення `name` для будь–якої функції не обов’язково посилається на змінну з таким самим ім’ям. Власнивість `name` не покликана допомагати у відлагодженні, тому неможливо використати значення `name` для отримання посилання на функцію.\n+\n+## Роз’яснення подвійної ролі функцій\n+\n+в ECMAScript 5 та раніше, функції можна було створити двома способами: з, або без `new`. При використанні `new`, значення `this` всередині функції було новим об’єктом і цей об’єкт повертався, так я ілюстровано в цьому прикладі:\n+\n+```js\n+function Person(name) {\n+    this.name = name;\n+}\n+\n+var person = new Person(\"Nicholas\");\n+var notAPerson = Person(\"Nicholas\");\n+\n+console.log(person);        // \"[Object object]\"\n+console.log(notAPerson);    // \"undefined\"\n+```\n+\n+При створенні `notAPerson`, виклик `Person()` без `new` повертає `undefined` (та встановлює властивість `name` глобальному об’єкту у нестрогому режимі). В програмах на JavaScript прийнято, що `Person` з великої літери — це єдиний індикатор того, що функція має бути викликаною з використанням `new`. Таке подвійне призначення функцій призводило до плутанини і тому зазнало деяких змін у ECMAScript 6.\n+\n+JavaScript має два різних внутрішніх методи для функцій: `[[Call]]` та `[[Construct]]`. Коли функція викликається без `new`, виконується метод `[[Call]]`, який виконує тіло функцій так, як це описано в коді. Коли функція викликається з `new`, тоді викликається `[[Construct]]`. Метод `[[Construct]]` відповідальний за створення нового об’єкта, і тоді виконання тіла функції з `this`, встановленим для нового об’єкта. Функції, які мають метод `[[Construct]]` називаються *конструкторами*.\n+\n+I> Запам’ятайте, що не всі функції мають `[[Construct]]`, тому не всі функції можуть бути викликані з `new`.  Arrow–функції, про які буде йтись у відповідному розділі, не мають методу `[[Construct]]`.\n+\n+### Визначення того, як функція була викликана у ECMAScript 5\n+\n+Найпопулярніший спосіб визначити, що функція була викликана з `new` (а отже й з конструктором) у ECMAScript 5 — це використати `instanceof`, для прикладу:\n+\n+```js\n+function Person(name) {\n+    if (this instanceof Person) {\n+        this.name = name;   // використано new\n+    } else {\n+        throw new Error(\"You must use new with Person.\")\n+    }\n+}\n+\n+var person = new Person(\"Nicholas\");\n+var notAPerson = Person(\"Nicholas\");  // кидає помилку\n+```\n+\n+Тут значення `this` перевіряється чи воно відповідає конструтору, і якщо воно відповідає, то виконання виконується так, як і слід. Якщо `this` не відповідає `Person`, тоді кидається помилка. Це працює тому, що метод `[[Construct]]` створює новий екземпляр `Person` та присвоює його в `this`. На жаль, такий підхід недостатньо надійний, оскільки `this` може відповідати `Person` і без використання `new`, наприклад:\n+\n+```js\n+function Person(name) {\n+    if (this instanceof Person) {\n+        this.name = name;   // з використанням new\n+    } else {\n+        throw new Error(\"You must use new with Person.\")\n+    }\n+}\n+\n+var person = new Person(\"Nicholas\");\n+var notAPerson = Person.call(person, \"Michael\");    // працює!\n+```\n+\n+Виклику `Person.call()` передається змінна `person` в якості першого аргументу, що означає `this` встановлений в `person` всередині функції `Person`. Для функцій немає ніякого способу відрізнити це від виклику з `new`.\n+\n+### Метавластивість new.target\n+\n+Щоб вирішити цю проблему, ECMAScript 6 вводить *метавластивість* `new.target`. Метавластивість — це властивість для необ’єктів, яка надає додаткову інформацію, яка стосується цільового об’єкту (як от `new`). Коли метод `[[Construct]]` функції викликаний, `new.target` заповнюється цільовим об’єктом оператора `new`. Цей цільовий об’єкт є зазвичай новоствореним екземпляром об’єкту, який стає `this` всередині тіла функції. Якщо виконано `[[Call]]`, тоді `new.target` буде `undefined`.\n+\n+Ця нова метавластивість дозволяє вам безпечно перевіряти чи функція була викликана з `new`, простою перевіркою того, чи було встановлено `new.target`:\n+\n+```js\n+function Person(name) {\n+    if (typeof new.target !== \"undefined\") {\n+        this.name = name;   // з використанням new\n+    } else {\n+        throw new Error(\"You must use new with Person.\")\n+    }\n+}\n+\n+var person = new Person(\"Nicholas\");\n+var notAPerson = Person.call(person, \"Michael\");    // помилка!\n+```\n+\n+З використанням `new.target` замість `this instanceof Person`, конструктор `Person` тепер кидатиме помилку при використанні без `new`.\n+\n+Ви також можете перевірити, що `new.target` було викликано з певним конструктором. Для прикладу:\n+\n+```js\n+function Person(name) {\n+    if (typeof new.target === Person) {\n+        this.name = name;   // використовуючи new\n+    } else {\n+        throw new Error(\"You must use new with Person.\")\n+    }\n+}\n+\n+function AnotherPerson(name) {\n+    Person.call(this, name);\n+}\n+\n+var person = new Person(\"Nicholas\");\n+var anotherPerson = new AnotherPerson(\"Nicholas\");  // помилка!\n+```\n+\n+У цьому прикладі, `new.target` мусить бути `Person` для коректної роботи. Коли `new AnotherPerson(\"Nicholas\")` створюється, `new.target` встановлюється в `AnotherPerson`, тому наступний виклик `Person.call(this, name)` кине помилку попри те, що `new.target` буде встановлено.\n+\n+W> Увага: Використання `new.target` поза функцією призведе до помилки.\n+\n+Додаючи `new.target`, ECMAScript 6 допомагає прояснити деякі незрозумілості, пов’язані з викликом функцій. Продовжуючи тему, ECMAScript 6 також вводить раніше незрозумілу частину мови: оголошення функцій всередині блоків.\n+\n+## Блочні функції\n+\n+У ECMAScript 3 та раніше, оголошення функції всередині блоку (*блочні функції*) технічно був синтаксичною помилкою, проте всі браузери продовжували підтримувати це. На жаль, кожен браузер, що дозволяв такий синтаксис поводився по різному, тому було прийнято уникати оголошення функцій всередині блоків (найкращою альтернативою було використання функціональних виразів).\n+\n+Намагаючись обмежети таку несумісну поведінку, строгий режим в ECMAScript 5 призводив до помилки при кожному оголошенні функції всередині блоку:\n+\n+```js\n+\"use strict\";\n+\n+if (true) {\n+\n+    // Кидає синтаксичну помилку у ES5, але не в ES6\n+    function doSomething() {\n+        // ...\n+    }\n+}\n+```\n+\n+У ECMAScript 5, такий код кидає синтаксичну помилку. У ECMAScript 6, функція `doSomething()` розглядається як блочне оголошення і може бути доступною та викликаною всередині блоку, в якому вона була оголошена. Наприклад:\n+\n+```js\n+\"use strict\";\n+\n+if (true) {\n+\n+    console.log(typeof doSomething);        // \"function\"\n+\n+    function doSomething() {\n+        // ...\n+    }\n+\n+    doSomething();\n+}\n+\n+console.log(typeof doSomething);            // \"undefined\"\n+```\n+\n+Блочні функції виринають на вершину блоку, в якому вони були оголошені, тому `typeof doSomething` повертає `\"function\"` не дивлячись на те, що ця інструкція знаходиться перед оголошенням функції. Як тільки блок `if` закінчить виконання, `doSomething()` більше не існуватиме.\n+\n+### Коли використовувати блочні функції\n+\n+Блочні функції схожі на функціональні вирази з `let`. При такому визначенні,функції видаляються як тільки хід виконання програми виходить з блоку у якому вони були оголошені. Основна відмінність у тому, що блочні функції виринають на вершину блоку у якому вони оголошені. Функціональні вирази, що використовують `let` не виринають, як показано у цьому прикладі:\n+\n+```js\n+\"use strict\";\n+\n+if (true) {\n+\n+    console.log(typeof doSomething);        // кине помилку\n+\n+    let doSomething = function () {\n+        // ...\n+    }\n+\n+    doSomething();\n+}\n+\n+console.log(typeof doSomething);\n+```\n+\n+Тут виконання коду зупиниться коли `typeof doSomething` буде виконано, оскільки оператор `let`  ще не було виконано, залишивши `doSomething()` у ТМЗ. Знанючи цю відмінність, ви можете обирати де використовувати блочні функції, а де вирази з `let`, в заледності від того, чи потрібне вам виринання, чи ні.\n+\n+### Блочні функції у нестрогому режимі\n+\n+ECMAScript 6 також дозволяє блочні функції у нестрогому режимі, але з дещо іншою поведінкою. Замість виринання цього огологення на вершину блоку, вони будуть виринати на вершину функції, або глобального оточення в якому містяться. До прикладу:\n+\n+```js\n+// Поведінка ECMAScript 6\n+if (true) {\n+\n+    console.log(typeof doSomething);        // \"function\"\n+\n+    function doSomething() {\n+        // ...\n+    }\n+\n+    doSomething();\n+}\n+\n+console.log(typeof doSomething);            // \"function\"\n+```\n+\n+У цьому прикладі, `doSomething()` виринає у глобальну область видимості, тому вона існує поза блоком `if`. ECMAScript 6 стандартизує цю поведінку, щоб прибрати несумісну поведінку браузерів, яка існувала до цього, тож всі оточення ECMAScript 6 повинні працювати однаково.\n+\n+Можливість використання блочних функцій розширює ваші можливості оголошення функцій у JavaScript, проте ECMAScript 6 також вводить абсолютно новий спосіб оголошення функцій.\n+\n+## Arrow–функції\n+\n+Однією з найцікавіших частин ECMAScript 6 є *arrow–функції*. Arrow–функції — це, як можна здогадатись, функції, що оголошуються з новим синтаксисом, який використовує стрілку (\"arrow\") (`=>`). Проте arrow–функції мають кілька важливих відмінностей від JavaScript–функцій:\n+\n+* **Жодних `this`, `super`, `arguments`, та `new.target` зв’язувань** – значення `this`, `super`, `arguments`, та `new.target` всередині функції наслідується від найближчої зовнішньої не–arraw–функції. (`super` буде розгянуто у Главі 4.)\n+* **Не можуть викликатись з `new`** - аrrow–функції не мають методу `[[Construct]]` і тому не можуть використовуватись у якості конструкторів. Arrow–функції кидають помилку при використанні з `new`.\n+* **Жодних прототипів** - оскільки ви не можете використовувати `new` з arrow–функцією, немає потреби у прототипі. Властивості `prototype` у arrow–функції не існує.\n+* **Не можна змінювати `this`** - значення `this` всередині функції не може змінюватись. Воно залишається незмінним протягом усього життєвого циклу функції.\n+* **Жодного об’єкту `arguments`** - оскільки arrow–функції не мають зв’язування з `arguments`, ви мусите покладатись лише на іменовані та залишкові параметри для доступу до аргументів.\n+* **Ніяких дубльованих іменованих аргументів** - arrow–функції не можуть мати дубьованих іменованих параметрів у строгому та нестрогому режимах, на відміну він не–arrow–функцій, що не можуть мати їх лише у строгому режимі.\n+\n+Є кілька причин для цих відмінностей. Перша і найголовніша: зв’язування `this` є основним джерелом помилок у JavaScript. Дуже легко загубити значення `this` всередині функції, що може призвести до неочікуваної поведінки програми. Arrow–функції позбавляють нас цієї проблеми. Друге полягає у тому, що arrow–функцій можуть лише виконувати код з єдиним значенням `this`. Рушії JavaScript можуть легше оптимізувати такі операції, на відміну від звичайних функцій, які можуть бути використані в якості конструктора, або бути модифікованим іншим чином.\n+\n+Решту відмінностей спрямовані на те, щоб скоротити помилки та невизначеності пов’язані з arrow–функціями. Завдяки цьому JavaScript рушії зможуть краще оптимізувати виконання arrow–фукнцій.\n+\n+I> Зауважте: Arrow–також мають властивість `name`, яка формується за тим же правилом, як і в інших функцій.\n+\n+### Синтаксис аrrow–фукнцій\n+\n+Синтаксис arrow–функцій може бути різним, в залежності від того, якого результату ви намагаєтесь досягти. Усі варіанти починаються з аргументів функції, за якими слідує стрілка, за якою слідує тіло функції. Як аргументи, так і тіло можуть набувати різного вигляду, в залежності від використання. До прикладу, наступна arrow–функція приймає один аргумент та просто повертає його:\n+\n+```js\n+var reflect = value => value;\n+\n+// простіший запис для:\n+\n+var reflect = function(value) {\n+    return value;\n+};\n+```\n+\n+Коли arrow–функція приймає лише один аргумет, цей один аргумент можна використовувати без будь–якого іншого синтаксису. Далі слідує стрілка та вираз праворуч від стрілки, який буде обчислено та повернено. Не дивлячись на відсутність інструкції `return`, ця arrow–функція поверне перший аргумент, який було передано.\n+\n+Якщо ви передаєте більш ніж один аргумент, ви повинні огорнути ці аргументи круглими дужками, ось так:\n+\n+```js\n+var sum = (num1, num2) => num1 + num2;\n+\n+// простіший запис для:\n+\n+var sum = function(num1, num2) {\n+    return num1 + num2;\n+};\n+```\n+\n+Функція `sum()` просто додає два аргументи та повертає результат. Єдина відмінність між цією arrow–фунцією та функцією `reflect()` — аргументи огорнуті в круглі дужки та розділені комами (як і в звичайних функціях).\n+\n+Якщо функція не приймає аргументів, тоді ви повинні залишити порожні круглі дужки, як показано у прикладі:\n+\n+```js\n+var getName = () => \"Nicholas\";\n+\n+// простіший запис для:\n+\n+var getName = function() {\n+    return \"Nicholas\";\n+};\n+```\n+\n+Якщо вам потрібне більш традиційне тіло функції, що, можливо, складається з більш ніж одного виразу, тоді вам потрібно огорнути тіло функції у фігурні дужки та безпосередньо вказати значення, яке має бути повернутим, як у цій версії `sum()`:\n+\n+```js\n+var sum = (num1, num2) => {\n+    return num1 + num2;\n+};\n+\n+// простіший запис для:\n+\n+var sum = function(num1, num2) {\n+    return num1 + num2;\n+};\n+```\n+\n+Так чи інакше, ви можете розглядати все що між фігурними дужками як звичайну фукнцію, за вийнятком того, що `arguments` в ній буде недоступний.\n+\n+Якщо ви хочете створити функцію, яка не робить нічого, тоді вам потрібно написати порожні фігурні дужки:\n+\n+```js\n+var doNothing = () => {};\n+\n+// простіший запис для:\n+\n+var doNothing = function() {};\n+```\n+\n+Фігурні дужки використовуються для опису тіла функції і працює так само, як ви вже бачили в попередніх прикладах. Проте arrow–функція, що повертає літерал об’єкта, має бути огорненою у круглі дужеки. Наприклад:\n+\n+```js\n+var getTempItem = id => ({ id: id, name: \"Temp\" });\n+\n+// простіший запис для:\n+\n+var getTempItem = function(id) {\n+\n+    return {\n+        id: id,\n+        name: \"Temp\"\n+    };\n+};\n+```\n+\n+Огорнення літералу об’єкта у круглі дужки сигналізують, що фігурні дужки є літералом об’єкту, а не тілом функції.\n+\n+### Створення миттєво–виконуваних функціональних виразів\n+\n+Одним з найпопулярніших застосувань функцій в JavaScript є створення миттєво–виконуваних функціональних виразів (МВФВ). МВФВ дозволяють вам визначати анонімну функцію та викликати її миттєво, без збереження посилання. Такий підхід стає в нагоді, коли вам потрібно зробити область видимості, захищену від решти програми. Наприклад:\n+\n+```js\n+let person = function(name) {\n+\n+    return {\n+        getName: function() {\n+            return name;\n+        }\n+    };\n+\n+}(\"Nicholas\");\n+\n+console.log(person.getName());      // \"Nicholas\"\n+```\n+\n+У цьому коді, МВФВ використовується щоб створити об’єкт з методом `getName()`. Цей метод повертає значення `name`, роблячи `name` приватним значенням об’єкту, що повертається.","path":"manuscript/03-Functions.md","position":902,"original_position":902,"commit_id":"fb5dbabb9f238690205f6b825ec7a93bdd47ad27","original_commit_id":"fb5dbabb9f238690205f6b825ec7a93bdd47ad27","user":{"login":"closedalexandr","id":17600166,"avatar_url":"https://avatars.githubusercontent.com/u/17600166?v=3","gravatar_id":"","url":"https://api.github.com/users/closedalexandr","html_url":"https://github.com/closedalexandr","followers_url":"https://api.github.com/users/closedalexandr/followers","following_url":"https://api.github.com/users/closedalexandr/following{/other_user}","gists_url":"https://api.github.com/users/closedalexandr/gists{/gist_id}","starred_url":"https://api.github.com/users/closedalexandr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/closedalexandr/subscriptions","organizations_url":"https://api.github.com/users/closedalexandr/orgs","repos_url":"https://api.github.com/users/closedalexandr/repos","events_url":"https://api.github.com/users/closedalexandr/events{/privacy}","received_events_url":"https://api.github.com/users/closedalexandr/received_events","type":"User","site_admin":false},"body":"Використовується, щоб створити...\r\nОб'єкта","created_at":"2016-05-04T14:15:36Z","updated_at":"2016-05-04T14:15:36Z","html_url":"https://github.com/denysdovhan/understandinges6ua/pull/4#discussion_r62045939","pull_request_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/pulls/4","_links":{"self":{"href":"https://api.github.com/repos/denysdovhan/understandinges6ua/pulls/comments/62045939"},"html":{"href":"https://github.com/denysdovhan/understandinges6ua/pull/4#discussion_r62045939"},"pull_request":{"href":"https://api.github.com/repos/denysdovhan/understandinges6ua/pulls/4"}}},"pull_request":{"url":"https://api.github.com/repos/denysdovhan/understandinges6ua/pulls/4","id":63468081,"html_url":"https://github.com/denysdovhan/understandinges6ua/pull/4","diff_url":"https://github.com/denysdovhan/understandinges6ua/pull/4.diff","patch_url":"https://github.com/denysdovhan/understandinges6ua/pull/4.patch","issue_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/issues/4","number":4,"state":"open","locked":false,"title":"Translate “03 Funcitons”","user":{"login":"denysdovhan","id":3459374,"avatar_url":"https://avatars.githubusercontent.com/u/3459374?v=3","gravatar_id":"","url":"https://api.github.com/users/denysdovhan","html_url":"https://github.com/denysdovhan","followers_url":"https://api.github.com/users/denysdovhan/followers","following_url":"https://api.github.com/users/denysdovhan/following{/other_user}","gists_url":"https://api.github.com/users/denysdovhan/gists{/gist_id}","starred_url":"https://api.github.com/users/denysdovhan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/denysdovhan/subscriptions","organizations_url":"https://api.github.com/users/denysdovhan/orgs","repos_url":"https://api.github.com/users/denysdovhan/repos","events_url":"https://api.github.com/users/denysdovhan/events{/privacy}","received_events_url":"https://api.github.com/users/denysdovhan/received_events","type":"User","site_admin":false},"body":"Translate [`03-Functions.md`](https://github.com/nzakas/understandinges6/blob/master/manuscript/03-Functions.md).","created_at":"2016-03-19T13:37:24Z","updated_at":"2016-05-04T14:15:36Z","closed_at":null,"merged_at":null,"merge_commit_sha":"18d94a5f2c4bd4a49b8dd4f5ecb07796628ad573","assignee":{"login":"denysdovhan","id":3459374,"avatar_url":"https://avatars.githubusercontent.com/u/3459374?v=3","gravatar_id":"","url":"https://api.github.com/users/denysdovhan","html_url":"https://github.com/denysdovhan","followers_url":"https://api.github.com/users/denysdovhan/followers","following_url":"https://api.github.com/users/denysdovhan/following{/other_user}","gists_url":"https://api.github.com/users/denysdovhan/gists{/gist_id}","starred_url":"https://api.github.com/users/denysdovhan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/denysdovhan/subscriptions","organizations_url":"https://api.github.com/users/denysdovhan/orgs","repos_url":"https://api.github.com/users/denysdovhan/repos","events_url":"https://api.github.com/users/denysdovhan/events{/privacy}","received_events_url":"https://api.github.com/users/denysdovhan/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/pulls/4/commits","review_comments_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/pulls/4/comments","review_comment_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/pulls/comments{/number}","comments_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/issues/4/comments","statuses_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/statuses/fb5dbabb9f238690205f6b825ec7a93bdd47ad27","head":{"label":"denysdovhan:03-functions","ref":"03-functions","sha":"fb5dbabb9f238690205f6b825ec7a93bdd47ad27","user":{"login":"denysdovhan","id":3459374,"avatar_url":"https://avatars.githubusercontent.com/u/3459374?v=3","gravatar_id":"","url":"https://api.github.com/users/denysdovhan","html_url":"https://github.com/denysdovhan","followers_url":"https://api.github.com/users/denysdovhan/followers","following_url":"https://api.github.com/users/denysdovhan/following{/other_user}","gists_url":"https://api.github.com/users/denysdovhan/gists{/gist_id}","starred_url":"https://api.github.com/users/denysdovhan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/denysdovhan/subscriptions","organizations_url":"https://api.github.com/users/denysdovhan/orgs","repos_url":"https://api.github.com/users/denysdovhan/repos","events_url":"https://api.github.com/users/denysdovhan/events{/privacy}","received_events_url":"https://api.github.com/users/denysdovhan/received_events","type":"User","site_admin":false},"repo":{"id":49322520,"name":"understandinges6ua","full_name":"denysdovhan/understandinges6ua","owner":{"login":"denysdovhan","id":3459374,"avatar_url":"https://avatars.githubusercontent.com/u/3459374?v=3","gravatar_id":"","url":"https://api.github.com/users/denysdovhan","html_url":"https://github.com/denysdovhan","followers_url":"https://api.github.com/users/denysdovhan/followers","following_url":"https://api.github.com/users/denysdovhan/following{/other_user}","gists_url":"https://api.github.com/users/denysdovhan/gists{/gist_id}","starred_url":"https://api.github.com/users/denysdovhan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/denysdovhan/subscriptions","organizations_url":"https://api.github.com/users/denysdovhan/orgs","repos_url":"https://api.github.com/users/denysdovhan/repos","events_url":"https://api.github.com/users/denysdovhan/events{/privacy}","received_events_url":"https://api.github.com/users/denysdovhan/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/denysdovhan/understandinges6ua","description":"Ukrainian translation of “Understanding ES6” by @nzakas","fork":false,"url":"https://api.github.com/repos/denysdovhan/understandinges6ua","forks_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/forks","keys_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/keys{/key_id}","collaborators_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/teams","hooks_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/hooks","issue_events_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/issues/events{/number}","events_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/events","assignees_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/assignees{/user}","branches_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/branches{/branch}","tags_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/tags","blobs_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/git/refs{/sha}","trees_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/git/trees{/sha}","statuses_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/statuses/{sha}","languages_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/languages","stargazers_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/stargazers","contributors_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/contributors","subscribers_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/subscribers","subscription_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/subscription","commits_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/commits{/sha}","git_commits_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/git/commits{/sha}","comments_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/comments{/number}","issue_comment_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/issues/comments{/number}","contents_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/contents/{+path}","compare_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/compare/{base}...{head}","merges_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/merges","archive_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/downloads","issues_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/issues{/number}","pulls_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/pulls{/number}","milestones_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/milestones{/number}","notifications_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/labels{/name}","releases_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/releases{/id}","deployments_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/deployments","created_at":"2016-01-09T11:57:24Z","updated_at":"2016-04-15T04:34:49Z","pushed_at":"2016-05-01T21:11:32Z","git_url":"git://github.com/denysdovhan/understandinges6ua.git","ssh_url":"git@github.com:denysdovhan/understandinges6ua.git","clone_url":"https://github.com/denysdovhan/understandinges6ua.git","svn_url":"https://github.com/denysdovhan/understandinges6ua","homepage":"http://understandinges6.denysdovhan.com","size":1709,"stargazers_count":21,"watchers_count":21,"language":null,"has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":6,"mirror_url":null,"open_issues_count":12,"forks":6,"open_issues":12,"watchers":21,"default_branch":"master"}},"base":{"label":"denysdovhan:master","ref":"master","sha":"148f3bbd927b0a74cae94344e6f402c04c97e4f8","user":{"login":"denysdovhan","id":3459374,"avatar_url":"https://avatars.githubusercontent.com/u/3459374?v=3","gravatar_id":"","url":"https://api.github.com/users/denysdovhan","html_url":"https://github.com/denysdovhan","followers_url":"https://api.github.com/users/denysdovhan/followers","following_url":"https://api.github.com/users/denysdovhan/following{/other_user}","gists_url":"https://api.github.com/users/denysdovhan/gists{/gist_id}","starred_url":"https://api.github.com/users/denysdovhan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/denysdovhan/subscriptions","organizations_url":"https://api.github.com/users/denysdovhan/orgs","repos_url":"https://api.github.com/users/denysdovhan/repos","events_url":"https://api.github.com/users/denysdovhan/events{/privacy}","received_events_url":"https://api.github.com/users/denysdovhan/received_events","type":"User","site_admin":false},"repo":{"id":49322520,"name":"understandinges6ua","full_name":"denysdovhan/understandinges6ua","owner":{"login":"denysdovhan","id":3459374,"avatar_url":"https://avatars.githubusercontent.com/u/3459374?v=3","gravatar_id":"","url":"https://api.github.com/users/denysdovhan","html_url":"https://github.com/denysdovhan","followers_url":"https://api.github.com/users/denysdovhan/followers","following_url":"https://api.github.com/users/denysdovhan/following{/other_user}","gists_url":"https://api.github.com/users/denysdovhan/gists{/gist_id}","starred_url":"https://api.github.com/users/denysdovhan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/denysdovhan/subscriptions","organizations_url":"https://api.github.com/users/denysdovhan/orgs","repos_url":"https://api.github.com/users/denysdovhan/repos","events_url":"https://api.github.com/users/denysdovhan/events{/privacy}","received_events_url":"https://api.github.com/users/denysdovhan/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/denysdovhan/understandinges6ua","description":"Ukrainian translation of “Understanding ES6” by @nzakas","fork":false,"url":"https://api.github.com/repos/denysdovhan/understandinges6ua","forks_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/forks","keys_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/keys{/key_id}","collaborators_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/teams","hooks_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/hooks","issue_events_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/issues/events{/number}","events_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/events","assignees_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/assignees{/user}","branches_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/branches{/branch}","tags_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/tags","blobs_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/git/refs{/sha}","trees_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/git/trees{/sha}","statuses_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/statuses/{sha}","languages_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/languages","stargazers_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/stargazers","contributors_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/contributors","subscribers_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/subscribers","subscription_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/subscription","commits_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/commits{/sha}","git_commits_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/git/commits{/sha}","comments_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/comments{/number}","issue_comment_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/issues/comments{/number}","contents_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/contents/{+path}","compare_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/compare/{base}...{head}","merges_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/merges","archive_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/downloads","issues_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/issues{/number}","pulls_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/pulls{/number}","milestones_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/milestones{/number}","notifications_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/labels{/name}","releases_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/releases{/id}","deployments_url":"https://api.github.com/repos/denysdovhan/understandinges6ua/deployments","created_at":"2016-01-09T11:57:24Z","updated_at":"2016-04-15T04:34:49Z","pushed_at":"2016-05-01T21:11:32Z","git_url":"git://github.com/denysdovhan/understandinges6ua.git","ssh_url":"git@github.com:denysdovhan/understandinges6ua.git","clone_url":"https://github.com/denysdovhan/understandinges6ua.git","svn_url":"https://github.com/denysdovhan/understandinges6ua","homepage":"http://understandinges6.denysdovhan.com","size":1709,"stargazers_count":21,"watchers_count":21,"language":null,"has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":6,"mirror_url":null,"open_issues_count":12,"forks":6,"open_issues":12,"watchers":21,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/denysdovhan/understandinges6ua/pulls/4"},"html":{"href":"https://github.com/denysdovhan/understandinges6ua/pull/4"},"issue":{"href":"https://api.github.com/repos/denysdovhan/understandinges6ua/issues/4"},"comments":{"href":"https://api.github.com/repos/denysdovhan/understandinges6ua/issues/4/comments"},"review_comments":{"href":"https://api.github.com/repos/denysdovhan/understandinges6ua/pulls/4/comments"},"review_comment":{"href":"https://api.github.com/repos/denysdovhan/understandinges6ua/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/denysdovhan/understandinges6ua/pulls/4/commits"},"statuses":{"href":"https://api.github.com/repos/denysdovhan/understandinges6ua/statuses/fb5dbabb9f238690205f6b825ec7a93bdd47ad27"}}}}