diff --git a/1-js/06-advanced-functions/10-bind/2-write-to-object-after-bind/solution.md b/1-js/06-advanced-functions/10-bind/2-write-to-object-after-bind/solution.md index 737a14481..b98ba59c7 100644 --- a/1-js/06-advanced-functions/10-bind/2-write-to-object-after-bind/solution.md +++ b/1-js/06-advanced-functions/10-bind/2-write-to-object-after-bind/solution.md @@ -1,4 +1,4 @@ -The answer: `null`. +Відповідь: `null`. ```js run @@ -13,6 +13,6 @@ let user = { user.g(); ``` -The context of a bound function is hard-fixed. There's just no way to further change it. +Контекст прив’язаної функції жорстко-фіксований. Немає способу змінити це в подальшому. -So even while we run `user.g()`, the original function is called with `this=null`. +Так чином в той час як ми запускаємо `user.g()`, функція `f` викликається з `this=null`. diff --git a/1-js/06-advanced-functions/10-bind/2-write-to-object-after-bind/task.md b/1-js/06-advanced-functions/10-bind/2-write-to-object-after-bind/task.md index 6d7e1fb24..4de9f88e4 100644 --- a/1-js/06-advanced-functions/10-bind/2-write-to-object-after-bind/task.md +++ b/1-js/06-advanced-functions/10-bind/2-write-to-object-after-bind/task.md @@ -2,9 +2,9 @@ importance: 5 --- -# Bound function as a method +# Прив’язана функція як метод -What will be the output? +Що виведе функція? ```js function f() { diff --git a/1-js/06-advanced-functions/10-bind/3-second-bind/solution.md b/1-js/06-advanced-functions/10-bind/3-second-bind/solution.md index 97e1c2809..fc209c68f 100644 --- a/1-js/06-advanced-functions/10-bind/3-second-bind/solution.md +++ b/1-js/06-advanced-functions/10-bind/3-second-bind/solution.md @@ -1,15 +1,15 @@ -The answer: **John**. +Відповідь: **Іван**. ```js run no-beautify function f() { alert(this.name); } -f = f.bind( {name: "John"} ).bind( {name: "Pete"} ); +f = f.bind( {name: "Іван"} ).bind( {name: "Христя"} ); -f(); // John +f(); // Іван ``` -The exotic [bound function](https://tc39.github.io/ecma262/#sec-bound-function-exotic-objects) object returned by `f.bind(...)` remembers the context (and arguments if provided) only at creation time. +Екзотичний об’єкт [прив’язаної функції](https://tc39.github.io/ecma262/#sec-bound-function-exotic-objects) повертається від `f.bind(...)`, що запам’ятовує контекст (та аргументи, якщо передані) тільки під час створення. -A function cannot be re-bound. +Функція не може бути переприв’язана. diff --git a/1-js/06-advanced-functions/10-bind/3-second-bind/task.md b/1-js/06-advanced-functions/10-bind/3-second-bind/task.md index 5daf053c6..f4e12ae0e 100644 --- a/1-js/06-advanced-functions/10-bind/3-second-bind/task.md +++ b/1-js/06-advanced-functions/10-bind/3-second-bind/task.md @@ -2,18 +2,18 @@ importance: 5 --- -# Second bind +# Друга прив’язка -Can we change `this` by additional binding? +Чи можемо ми змінити `this` за допомогою додаткового прив’язування? -What will be the output? +Який результат буде виведено? ```js no-beautify function f() { alert(this.name); } -f = f.bind( {name: "John"} ).bind( {name: "Ann" } ); +f = f.bind( {name: "Іван"} ).bind( {name: "Христя" } ); f(); ``` diff --git a/1-js/06-advanced-functions/10-bind/4-function-property-after-bind/solution.md b/1-js/06-advanced-functions/10-bind/4-function-property-after-bind/solution.md index 181555d95..fe7ba11c3 100644 --- a/1-js/06-advanced-functions/10-bind/4-function-property-after-bind/solution.md +++ b/1-js/06-advanced-functions/10-bind/4-function-property-after-bind/solution.md @@ -1,4 +1,4 @@ -The answer: `undefined`. +Відповідь: `undefined`. -The result of `bind` is another object. It does not have the `test` property. +Результатом `bind` є інший об’єкт. Він не містить властивість `test`. diff --git a/1-js/06-advanced-functions/10-bind/4-function-property-after-bind/task.md b/1-js/06-advanced-functions/10-bind/4-function-property-after-bind/task.md index d6cfb44bf..b5f92494a 100644 --- a/1-js/06-advanced-functions/10-bind/4-function-property-after-bind/task.md +++ b/1-js/06-advanced-functions/10-bind/4-function-property-after-bind/task.md @@ -2,9 +2,9 @@ importance: 5 --- -# Function property after bind +# Властивість функції після прив’язки -There's a value in the property of a function. Will it change after `bind`? Why, or why not? +Функції присвоєна властивість зі значенням. Чи зміниться вона після `bind`? Чому? ```js run function sayHi() { @@ -14,10 +14,10 @@ sayHi.test = 5; *!* let bound = sayHi.bind({ - name: "John" + name: "Іван" }); -alert( bound.test ); // what will be the output? why? +alert( bound.test ); // що виведе функція? Чому? */!* ``` diff --git a/1-js/06-advanced-functions/10-bind/5-question-use-bind/solution.md b/1-js/06-advanced-functions/10-bind/5-question-use-bind/solution.md index 403107ca6..1e93196ec 100644 --- a/1-js/06-advanced-functions/10-bind/5-question-use-bind/solution.md +++ b/1-js/06-advanced-functions/10-bind/5-question-use-bind/solution.md @@ -1,26 +1,26 @@ -The error occurs because `ask` gets functions `loginOk/loginFail` without the object. +Помилка виникає тому що `askPassword` отримує функції `loginOk/loginFail` без об’єкту. -When it calls them, they naturally assume `this=undefined`. +Коли вона викликає їх, їх контекст втрачено `this=undefined`. -Let's `bind` the context: +Спробуємо використати `bind`, щоб прив’язати контекст: ```js run function askPassword(ok, fail) { - let password = prompt("Password?", ''); + let password = prompt("Пароль?", ''); if (password == "rockstar") ok(); else fail(); } let user = { - name: 'John', + name: 'Іван', loginOk() { - alert(`${this.name} logged in`); + alert(`${this.name} увійшов`); }, loginFail() { - alert(`${this.name} failed to log in`); + alert(`${this.name} виконав невдалу спробу входу`); }, }; @@ -30,14 +30,14 @@ askPassword(user.loginOk.bind(user), user.loginFail.bind(user)); */!* ``` -Now it works. +Тепер це працює. -An alternative solution could be: +Альтернативне рішення могло б бути: ```js //... askPassword(() => user.loginOk(), () => user.loginFail()); ``` -Usually that also works and looks good. +Зазвичай це також працює та чудово виглядає. -It's a bit less reliable though in more complex situations where `user` variable might change *after* `askPassword` is called, but *before* the visitor answers and calls `() => user.loginOk()`. +Це менш найдіно, так як в більш складних ситуаціях змінна `user` може змінитися *після* виклику `askPassword`, але *перед* викликом `() => user.loginOk()`. diff --git a/1-js/06-advanced-functions/10-bind/5-question-use-bind/task.md b/1-js/06-advanced-functions/10-bind/5-question-use-bind/task.md index fe6a9b4eb..784a09cb5 100644 --- a/1-js/06-advanced-functions/10-bind/5-question-use-bind/task.md +++ b/1-js/06-advanced-functions/10-bind/5-question-use-bind/task.md @@ -2,30 +2,30 @@ importance: 5 --- -# Fix a function that loses "this" +# Виправте функцію, яка втратила 'this' -The call to `askPassword()` in the code below should check the password and then call `user.loginOk/loginFail` depending on the answer. +Виклик `askPassword()` в коді наведеному нижче повинен перевіряти пароль та викликати `user.loginOk/loginFail` в залежності від відповіді. -But it leads to an error. Why? +Але виконання коду призводить до помилки. Чому? -Fix the highlighted line for everything to start working right (other lines are not to be changed). +Виправте виділений рядок, щоб код запрацював правильно (інші рядки не мають бути змінені). ```js run function askPassword(ok, fail) { - let password = prompt("Password?", ''); + let password = prompt("Пароль?", ''); if (password == "rockstar") ok(); else fail(); } let user = { - name: 'John', + name: 'Іван', loginOk() { - alert(`${this.name} logged in`); + alert(`${this.name} увійшов`); }, loginFail() { - alert(`${this.name} failed to log in`); + alert(`${this.name} виконав невдалу спробу входу`); }, }; diff --git a/1-js/06-advanced-functions/10-bind/6-ask-partial/solution.md b/1-js/06-advanced-functions/10-bind/6-ask-partial/solution.md index 3284c943b..83ce2da46 100644 --- a/1-js/06-advanced-functions/10-bind/6-ask-partial/solution.md +++ b/1-js/06-advanced-functions/10-bind/6-ask-partial/solution.md @@ -1,14 +1,14 @@ -1. Either use a wrapper function, an arrow to be concise: +1. Або використовуйте стрілкову функцію як функцію-обгортку для короткого запису: ```js askPassword(() => user.login(true), () => user.login(false)); ``` - Now it gets `user` from outer variables and runs it the normal way. + Тепер `user` отримується з зовнішніх змінних та код виконується правильно. -2. Or create a partial function from `user.login` that uses `user` as the context and has the correct first argument: +2. Або створіть частково застосовану функцію `user.login`, що використовує `user` як контекст та має правильний аргумент: ```js diff --git a/1-js/06-advanced-functions/10-bind/6-ask-partial/task.md b/1-js/06-advanced-functions/10-bind/6-ask-partial/task.md index c90851c2b..97feda06e 100644 --- a/1-js/06-advanced-functions/10-bind/6-ask-partial/task.md +++ b/1-js/06-advanced-functions/10-bind/6-ask-partial/task.md @@ -2,26 +2,26 @@ importance: 5 --- -# Partial application for login +# Часткове застосування для логіну -The task is a little more complex variant of . +Задача трохи складніша ніж . -The `user` object was modified. Now instead of two functions `loginOk/loginFail`, it has a single function `user.login(true/false)`. +Об’єкт `user` був змінений. Тепер замість двох функцій `loginOk/loginFail`, він має одну функцію `user.login(true/false)`. -What should we pass `askPassword` in the code below, so that it calls `user.login(true)` as `ok` and `user.login(false)` as `fail`? +Що ми маємо передати `askPassword` в коді нижче, щоб вона викликала `user.login(true)` при `ok` та `user.login(false)` при `fail`? ```js function askPassword(ok, fail) { - let password = prompt("Password?", ''); + let password = prompt("Пароль?", ''); if (password == "rockstar") ok(); else fail(); } let user = { - name: 'John', + name: 'Іван', login(result) { - alert( this.name + (result ? ' logged in' : ' failed to log in') ); + alert( this.name + (result ? ' увійшов' : ' виконав невдалу спробу входу') ); } }; @@ -30,5 +30,5 @@ askPassword(?, ?); // ? */!* ``` -Your changes should only modify the highlighted fragment. +Вносіть зміни тільки у виділений рядок. diff --git a/1-js/06-advanced-functions/10-bind/article.md b/1-js/06-advanced-functions/10-bind/article.md index 3cee4fe83..0eb6fd754 100644 --- a/1-js/06-advanced-functions/10-bind/article.md +++ b/1-js/06-advanced-functions/10-bind/article.md @@ -3,116 +3,116 @@ libs: --- -# Function binding +# Прив’язка контексту до функції -When passing object methods as callbacks, for instance to `setTimeout`, there's a known problem: "losing `this`". +Передаючи методи об’єкту в якості колбеків, наприклад в `setTimeout`, існує відома проблема: "втрата `this`". -In this chapter we'll see the ways to fix it. +В цьому розділі ми розглянемо способи як це можливо виправити. -## Losing "this" +## Втрата "this" -We've already seen examples of losing `this`. Once a method is passed somewhere separately from the object -- `this` is lost. +Ми вже розглядали приклади втрати `this`. Якщо метод передавався окремо від об’єкта -- `this` втрачається. -Here's how it may happen with `setTimeout`: +В прикладі наведено як це відбувається з `setTimeout`: ```js run let user = { - firstName: "John", + firstName: "Іван", sayHi() { - alert(`Hello, ${this.firstName}!`); + alert(`Привіт, ${this.firstName}!`); } }; *!* -setTimeout(user.sayHi, 1000); // Hello, undefined! +setTimeout(user.sayHi, 1000); // Привіт, undefined! */!* ``` -As we can see, the output shows not "John" as `this.firstName`, but `undefined`! +Як ми можемо спостерігати, модальне вікно браузера відображає не "Іван" як `this.firstName`, а `undefined`! -That's because `setTimeout` got the function `user.sayHi`, separately from the object. The last line can be rewritten as: +Це тому що `setTimeout` отримав функцію `user.sayHi` окремо від об’єкта. Останній рядок бути переписаний наступним чином: ```js let f = user.sayHi; -setTimeout(f, 1000); // lost user context +setTimeout(f, 1000); // втрата контексту об’єкта user ``` -The method `setTimeout` in-browser is a little special: it sets `this=window` for the function call (for Node.js, `this` becomes the timer object, but doesn't really matter here). So for `this.firstName` it tries to get `window.firstName`, which does not exist. In other similar cases, usually `this` just becomes `undefined`. +Метод `setTimeout` в браузері трохи особливий: він встановлює `this=window` під час виклику функції (для Node.js, `this` стане об’єкт таймеру, але це не дуже важливо у цьому випадку). Таким чином для `this.firstName` метод намагається отримати `window.firstName`, що не існує. В інших схожих випадках, зазвичай `this` просто стає `undefined`. -The task is quite typical -- we want to pass an object method somewhere else (here -- to the scheduler) where it will be called. How to make sure that it will be called in the right context? +Задача досить типова -- ми хочемо передати метод об’єкту деінде (в цьому випадку -- в планувальник) де він буде викликаний. Як бути впевненими в тому, що він буде викликаний з правильним контекстом? -## Solution 1: a wrapper +## Рішення 1: обгортка -The simplest solution is to use a wrapping function: +Найпростіше рішення - використати функцію обгортку: ```js run let user = { - firstName: "John", + firstName: "Іван", sayHi() { - alert(`Hello, ${this.firstName}!`); + alert(`Привіт, ${this.firstName}!`); } }; *!* setTimeout(function() { - user.sayHi(); // Hello, John! + user.sayHi(); // Привіт, Іван! }, 1000); */!* ``` -Now it works, because it receives `user` from the outer lexical environment, and then calls the method normally. +Тепер це працює, тому що ми отримали `user` з зовнішнього лексичного оточення, і потім викликали метод. -The same, but shorter: +Аналогічний запис, тільки коротший: ```js -setTimeout(() => user.sayHi(), 1000); // Hello, John! +setTimeout(() => user.sayHi(), 1000); // Привіт, Іван! ``` -Looks fine, but a slight vulnerability appears in our code structure. +Виглядає чудово, але з’являється легка вразливість в структурі нашого коду. -What if before `setTimeout` triggers (there's one second delay!) `user` changes value? Then, suddenly, it will call the wrong object! +Що якщо перед спрацюванням `setTimeout` (з однією секундою затримки!) `user` змінить значення? Тоді, неочікувано, він викличе неправильний об’єкт! ```js run let user = { - firstName: "John", + firstName: "Іван", sayHi() { - alert(`Hello, ${this.firstName}!`); + alert(`Привіт, ${this.firstName}!`); } }; setTimeout(() => user.sayHi(), 1000); -// ...the value of user changes within 1 second +// ...значення user змінюється впродовж 1 секунди user = { - sayHi() { alert("Another user in setTimeout!"); } + sayHi() { alert("Інший user в setTimeout!"); } }; -// Another user in setTimeout! +// Інший user в setTimeout! ``` -The next solution guarantees that such thing won't happen. +Наступне рішення гарантує, що така ситуація не трапиться. -## Solution 2: bind +## Рішення 2: прив’язка -Functions provide a built-in method [bind](mdn:js/Function/bind) that allows to fix `this`. +Функції надають нам вбудований метод [bind](mdn:js/Function/bind), що дозволяє зберегти правильний `this`. -The basic syntax is: +Основний синтаксис: ```js -// more complex syntax will come a little later +// більш складний синтаксис буде трохи пізніше let boundFunc = func.bind(context); ``` -The result of `func.bind(context)` is a special function-like "exotic object", that is callable as function and transparently passes the call to `func` setting `this=context`. +Результатом `func.bind(context)` буде певний "екзотичний об’єкт", який може бути викликаний як функція та передає виклику `func` встановлений контекст `this=context`. -In other words, calling `boundFunc` is like `func` with fixed `this`. +Іншими словами, виклик `boundFunc` це як виклик `func` з виправленим `this`. -For instance, here `funcUser` passes a call to `func` with `this=user`: +Наприклад, тут `funcUser` передає виклик `func` з `this=user`: -```js run +```js run let user = { - firstName: "John" + firstName: "Іван" }; function func() { @@ -121,39 +121,39 @@ function func() { *!* let funcUser = func.bind(user); -funcUser(); // John +funcUser(); // Іван */!* ``` -Here `func.bind(user)` as a "bound variant" of `func`, with fixed `this=user`. +Тут `func.bind(user)` як "прив’язаний варіант" функції `func`, з виправленим `this=user`. -All arguments are passed to the original `func` "as is", for instance: +Всі аргументи передаються початковій функції `func` "як є", наприклад: -```js run +```js run let user = { - firstName: "John" + firstName: "Іван" }; function func(phrase) { alert(phrase + ', ' + this.firstName); } -// bind this to user +// прив’язка до user let funcUser = func.bind(user); *!* -funcUser("Hello"); // Hello, John (argument "Hello" is passed, and this=user) +funcUser("Привіт"); // Привіт, Іван (переданий аргумент "Привіт" та this=user) */!* ``` -Now let's try with an object method: +Тепер спробуємо з методом об’єкту: ```js run let user = { - firstName: "John", + firstName: "Іван", sayHi() { - alert(`Hello, ${this.firstName}!`); + alert(`Привіт, ${this.firstName}!`); } }; @@ -161,25 +161,25 @@ let user = { let sayHi = user.sayHi.bind(user); // (*) */!* -// can run it without an object -sayHi(); // Hello, John! +// можемо викликати без об’єкту +sayHi(); // Привіт, Іван! -setTimeout(sayHi, 1000); // Hello, John! +setTimeout(sayHi, 1000); // Привіт, Іван! -// even if the value of user changes within 1 second -// sayHi uses the pre-bound value which is reference to the old user object +// навіть якщо значення user зміниться впродовж 1 секунди +// sayHi використовує прив’язане значення, яке посилається на старий об’єкт user user = { - sayHi() { alert("Another user in setTimeout!"); } + sayHi() { alert("Інший user в setTimeout!"); } }; ``` -In the line `(*)` we take the method `user.sayHi` and bind it to `user`. The `sayHi` is a "bound" function, that can be called alone or passed to `setTimeout` -- doesn't matter, the context will be right. +В строчці `(*)` ми взяли метод `user.sayHi` та прив’язали його до `user`. `sayHi` є "прив’язаною" функцією, що може бути викликана окремо або передана до `setTimeout` -- не важливо, контекст буде правильний. -Here we can see that arguments are passed "as is", only `this` is fixed by `bind`: +В цьому прикладі ми можемо бачити що аргументи передані "як є", тільки `this` виправлено за допомогою `bind`: ```js run let user = { - firstName: "John", + firstName: "Іван", say(phrase) { alert(`${phrase}, ${this.firstName}!`); } @@ -187,12 +187,12 @@ let user = { let say = user.say.bind(user); -say("Hello"); // Hello, John ("Hello" argument is passed to say) -say("Bye"); // Bye, John ("Bye" is passed to say) +say("Привіт"); // Привіт, Іван (Аргумент "Привіт" переданий функції say) +say("Бувай"); // Бувай, Іван ("Бувай" передане функції say) ``` -````smart header="Convenience method: `bindAll`" -If an object has many methods and we plan to actively pass it around, then we could bind them all in a loop: +````smart header="Зручний метод: `bindAll`" +Якщо об’єкт містить багато методів та ми плануємо активно їх передавати, тоді ми можемо прив’язати їх всіх за допомогою циклу: ```js for (let key in user) { @@ -202,24 +202,24 @@ for (let key in user) { } ``` -JavaScript libraries also provide functions for convenient mass binding , e.g. [_.bindAll(object, methodNames)](http://lodash.com/docs#bindAll) in lodash. +JavaScript бібліотеки також пропонуються функції для зручної масової прив’язки, наприклад [_.bindAll(object, methodNames)](http://lodash.com/docs#bindAll) в бібліотеці lodash. ```` -## Partial functions +## Часткове застосування -Until now we have only been talking about binding `this`. Let's take it a step further. +До цього моменту ми говорили тільки про прив’язку `this`. Зробимо крок далі. -We can bind not only `this`, but also arguments. That's rarely done, but sometimes can be handy. +Ми можемо прив’язати не тільки `this`, а також аргументи. Це робиться рідко, проте може бути інколи дуже зручним. -The full syntax of `bind`: +Повний синтаксис `bind`: ```js let bound = func.bind(context, [arg1], [arg2], ...); ``` -It allows to bind context as `this` and starting arguments of the function. +Це дозволяє прив’язати context як `this` та початкові аргументи функції. -For instance, we have a multiplication function `mul(a, b)`: +Наприклад, ми маємо функцію множення `mul(a, b)`: ```js function mul(a, b) { @@ -227,7 +227,7 @@ function mul(a, b) { } ``` -Let's use `bind` to create a function `double` on its base: +Використаємо `bind` щоб створити функцію `double` на її основі: ```js run function mul(a, b) { @@ -243,13 +243,13 @@ alert( double(4) ); // = mul(2, 4) = 8 alert( double(5) ); // = mul(2, 5) = 10 ``` -The call to `mul.bind(null, 2)` creates a new function `double` that passes calls to `mul`, fixing `null` as the context and `2` as the first argument. Further arguments are passed "as is". +Виклик `mul.bind(null, 2)` створює нову функцію `double` що передає виклик `mul`, встановлючи `null` як контекст та `2` як перший аргумент. Подальші аргументи передаються "як є". -That's called [partial function application](https://en.wikipedia.org/wiki/Partial_application) -- we create a new function by fixing some parameters of the existing one. +Це називається [часткове застосування](https://en.wikipedia.org/wiki/Partial_application) -- ми створюємо нову функцію виправляючи деякі параметри існуючої. -Please note that we actually don't use `this` here. But `bind` requires it, so we must put in something like `null`. +Зверніть увагу, що ми не використовували `this` в цьому прикладі. Проте `bind` вимагає цього, тому ми маємо передати щось як заглушку -- `null`. -The function `triple` in the code below triples the value: +Функція `triple` в коді нижче потроює значення: ```js run function mul(a, b) { @@ -265,23 +265,23 @@ alert( triple(4) ); // = mul(3, 4) = 12 alert( triple(5) ); // = mul(3, 5) = 15 ``` -Why do we usually make a partial function? +Чому ми використовуємо часткове застосування? -The benefit is that we can create an independent function with a readable name (`double`, `triple`). We can use it and not provide the first argument every time as it's fixed with `bind`. +Перевагою цього є те, що ми можемо створити незалежну функцію з читабельним ім’ям (`double`, `triple`). Ми можемо використовувати її та не передавати перший аргумент кожен раз, оскільки це замість нас виконує `bind`. -In other cases, partial application is useful when we have a very generic function and want a less universal variant of it for convenience. +В інших випадках, часткове застосування є корисним, коли ми маємо дуже загальну функцію та хочемо менш універсальний її варіант для зручності. -For instance, we have a function `send(from, to, text)`. Then, inside a `user` object we may want to use a partial variant of it: `sendTo(to, text)` that sends from the current user. +Наприклад, у нас є функція `send(from, to, text)`. Тоді, в середині об’єкту `user` ми можемо захотіти використати її частковий варіант: `sendTo(to, text)`, яка відправляє текст від поточного користувача. -## Going partial without context +## Використання часткового застосування без контексту -What if we'd like to fix some arguments, but not the context `this`? For example, for an object method. +Що якщо ми хочемо виправити деякі аргументи, але не контекст `this`? Наприклад, для методу об’єкта. -The native `bind` does not allow that. We can't just omit the context and jump to arguments. +Вбудований метод `bind` не дозволяє цього. Ми можемо просто опустити контекст та перейти до аргументів. -Fortunately, a function `partial` for binding only arguments can be easily implemented. +На щастя, функція `partial` для прив’язування тільки аргументів може бути реалізована дуже просто. -Like this: +Як тут: ```js run *!* @@ -292,37 +292,37 @@ function partial(func, ...argsBound) { } */!* -// Usage: +// Використання: let user = { - firstName: "John", + firstName: "Іван", say(time, phrase) { alert(`[${time}] ${this.firstName}: ${phrase}!`); } }; -// add a partial method with fixed time +// та метод partial з виправленим часом user.sayNow = partial(user.say, new Date().getHours() + ':' + new Date().getMinutes()); -user.sayNow("Hello"); +user.sayNow("Привіт"); // Something like: -// [10:00] John: Hello! +// [10:00] Іван: Привіт! ``` -The result of `partial(func[, arg1, arg2...])` call is a wrapper `(*)` that calls `func` with: -- Same `this` as it gets (for `user.sayNow` call it's `user`) -- Then gives it `...argsBound` -- arguments from the `partial` call (`"10:00"`) -- Then gives it `...args` -- arguments given to the wrapper (`"Hello"`) +Результатом виклику `partial(func[, arg1, arg2...])` є обгортка `(*)` що викликає `func` з: +- Те ж `this` яке воно отримує (для виклику `user.sayNow` це `user`) +- Передає йому `...argsBound` -- аргументи з виклику `partial` (`"10:00"`) +- Потім передає йому `...args` -- аргументи отримані з обгортки (`"Hello"`) -So easy to do it with the spread syntax, right? +Як бачите, це легко робиться за допомогою оператору розширення, чи не так? -Also there's a ready [_.partial](https://lodash.com/docs#partial) implementation from lodash library. +Також існує реалізація [_.partial](https://lodash.com/docs#partial) в бібліотеці lodash. -## Summary +## Підсумки -Method `func.bind(context, ...args)` returns a "bound variant" of function `func` that fixes the context `this` and first arguments if given. +Метод `func.bind(context, ...args)` повертає a "прив’язаний варіант" функції `func` який виправляє контекст `this` та аргументи, якщо вони передані. -Usually we apply `bind` to fix `this` for an object method, so that we can pass it somewhere. For example, to `setTimeout`. +Зазвичай ми застосовуємо `bind`, щоб виправити `this` для методу об’єкта та передати його деінде. Наприклад, в `setTimeout`. -When we fix some arguments of an existing function, the resulting (less universal) function is called *partially applied* or *partial*. +Коли ми виправляємо деякі аргументи існуючої функції, в результаті ми отримуємо (менш універсальну) функцію, яка називається *частково застосованою* або *частковою*. -Partials are convenient when we don't want to repeat the same argument over and over again. Like if we have a `send(from, to)` function, and `from` should always be the same for our task, we can get a partial and go on with it. +Часткові функції зручні, коли ми не хочемо повторно передавати одні й ті ж самі аргументи знову і знову. Наприклад, якщо ми маємо функцію `send(from, to)` та аргумент `from` постійно буде однаковим для нашої поточної задачі, ми можемо зробити частково застосовану функцію та використовувати її.