From 4f6e7e456f401721869ae8d2b83971d0d55666f1 Mon Sep 17 00:00:00 2001 From: Ivan Date: Sat, 25 Sep 2021 21:56:20 +0300 Subject: [PATCH 1/8] Function binding --- .../2-write-to-object-after-bind/solution.md | 6 +- .../2-write-to-object-after-bind/task.md | 6 +- .../10-bind/3-second-bind/solution.md | 10 +- .../10-bind/3-second-bind/task.md | 10 +- .../solution.md | 4 +- .../4-function-property-after-bind/task.md | 10 +- .../10-bind/5-question-use-bind/solution.md | 22 +- .../10-bind/5-question-use-bind/task.md | 18 +- .../10-bind/6-ask-partial/solution.md | 6 +- .../10-bind/6-ask-partial/task.md | 18 +- 1-js/06-advanced-functions/10-bind/article.md | 200 +++++++++--------- 11 files changed, 155 insertions(+), 155 deletions(-) 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..b349d5314 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..1fd4942db 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 @@ -1,10 +1,10 @@ -importance: 5 +важливість: 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..dacb90668 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..06e6d2f5d 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 @@ -1,19 +1,19 @@ -importance: 5 +важливість: 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..5aadf02e9 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..d81ac049f 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 @@ -1,10 +1,10 @@ -importance: 5 +важливість: 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..b0f33e437 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..2945bc806 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 @@ -1,31 +1,31 @@ -importance: 5 +важливість: 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..ddb3a2cbc 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..5c09780fd 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 @@ -1,27 +1,27 @@ -importance: 5 +важливість: 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..e569db528 100644 --- a/1-js/06-advanced-functions/10-bind/article.md +++ b/1-js/06-advanced-functions/10-bind/article.md @@ -3,116 +3,115 @@ 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? +Задача досить типова -- ми хочемо передати метод об'єкту деінде (в цьому випадку -- в планувальник) де він буде викликаний. Як бути впевненими в тому, що він буде викликаний з правильним контекстом? +## Рішення 1: обгортка -## Solution 1: a wrapper - -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 +120,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 +160,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 +186,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 +201,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 +226,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 +242,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 +264,24 @@ alert( triple(4) ); // = mul(3, 4) = 12 alert( triple(5) ); // = mul(3, 5) = 15 ``` -Why do we usually make a partial function? +Чому ми використовуємо часткове застосування? + +Перевагою цього є те, що ми можемо створити незалежну функцію з читабельним ім'ям (`double`, `triple`). Ми можемо використовувати її та не передавати перший аргумент кожен раз, оскільки це замість нас виконує `bind`. -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`. +В інших випадках, часткове застосування є корисним, коли ми маємо дуже загальну функцію та хочемо менш універсальний її варіант для зручності. -In other cases, partial application is useful when we have a very generic function and want a less universal variant of it for convenience. +Наприклад, у нас є функція `send(from, to, text)`. Тоді, в середині об'єкту `user` ми можемо захотіти використати її частковий варіант: `sendTo(to, text)`, яка відправляє текст від поточного користувача. -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. +## Використання часткового застосування без контексту -## Going partial without context +Що якщо ми хочемо виправити деякі аргументи, але не контекст `this`? Наприклад, для методу об'єкта. -What if we'd like to fix some arguments, but not the context `this`? For example, for an object method. +Вбудований метод `bind` не дозволяє цього. Ми можемо просто опустити контекст та перейти до аргументів. -The native `bind` does not allow that. We can't just omit the context and jump to arguments. +На щастя, функція `partial` для прив'язування тільки аргументів може бути реалізована дуже просто. -Fortunately, a function `partial` for binding only arguments can be easily implemented. -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` постійно буде однаковим для нашої поточної задачі, ми можемо зробити частково застосовану функцію та використовувати її. From 1aa9576d1a4443c27e677d816e6c2020cadbfd72 Mon Sep 17 00:00:00 2001 From: Ivan Date: Sat, 25 Sep 2021 23:26:02 +0300 Subject: [PATCH 2/8] Function binding --- 1-js/06-advanced-functions/10-bind/article.md | 1 + 1 file changed, 1 insertion(+) diff --git a/1-js/06-advanced-functions/10-bind/article.md b/1-js/06-advanced-functions/10-bind/article.md index e569db528..6dfe22976 100644 --- a/1-js/06-advanced-functions/10-bind/article.md +++ b/1-js/06-advanced-functions/10-bind/article.md @@ -40,6 +40,7 @@ setTimeout(f, 1000); // втрата контексту об`єкта user Метод `setTimeout` в браузері трохи особливий: він встановлює `this=window` під час виклику функції (для Node.js, `this` стане об'єкт таймеру, але це не дуже важливо у цьому випадку). Таким чином для `this.firstName` метод намагається отримати `window.firstName`, що не існує. В інших схожих випадках, зазвичай `this` просто стає `undefined`. Задача досить типова -- ми хочемо передати метод об'єкту деінде (в цьому випадку -- в планувальник) де він буде викликаний. Як бути впевненими в тому, що він буде викликаний з правильним контекстом? + ## Рішення 1: обгортка Найпростіше рішення - використати функцію обгортку: From 544c2b65873f683a5f4e5929762f509a3eb2540a Mon Sep 17 00:00:00 2001 From: Ivan Date: Sat, 25 Sep 2021 23:29:17 +0300 Subject: [PATCH 3/8] Function binding --- 1-js/06-advanced-functions/10-bind/article.md | 1 - 1 file changed, 1 deletion(-) diff --git a/1-js/06-advanced-functions/10-bind/article.md b/1-js/06-advanced-functions/10-bind/article.md index 6dfe22976..4e45705a9 100644 --- a/1-js/06-advanced-functions/10-bind/article.md +++ b/1-js/06-advanced-functions/10-bind/article.md @@ -281,7 +281,6 @@ alert( triple(5) ); // = mul(3, 5) = 15 На щастя, функція `partial` для прив'язування тільки аргументів може бути реалізована дуже просто. - Як тут: ```js run From b457b4766081f38548131fdd6a6eb583a72ade56 Mon Sep 17 00:00:00 2001 From: Taras Date: Sun, 26 Sep 2021 12:21:17 +0300 Subject: [PATCH 4/8] Update 1-js/06-advanced-functions/10-bind/2-write-to-object-after-bind/solution.md --- .../10-bind/2-write-to-object-after-bind/solution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 b349d5314..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 @@ -13,6 +13,6 @@ let user = { user.g(); ``` -Контекст прив'язаної функції жорстко-фіксований. Немає способу змінити це в подальшому. +Контекст прив’язаної функції жорстко-фіксований. Немає способу змінити це в подальшому. Так чином в той час як ми запускаємо `user.g()`, функція `f` викликається з `this=null`. From 53079ccb1abc23f8e08018f6f0691894fdd84778 Mon Sep 17 00:00:00 2001 From: Taras Date: Sun, 26 Sep 2021 12:22:03 +0300 Subject: [PATCH 5/8] Update 1-js/06-advanced-functions/10-bind/2-write-to-object-after-bind/task.md --- .../10-bind/2-write-to-object-after-bind/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 1fd4942db..e394f738f 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 @@ -1,4 +1,4 @@ -важливість: 5 +importance: 5 --- From 4c3d8aba32bfc39f26b8582d75caf9b4cd235b11 Mon Sep 17 00:00:00 2001 From: Ivan Date: Mon, 27 Sep 2021 13:23:01 +0300 Subject: [PATCH 6/8] Function binding --- .../2-write-to-object-after-bind/solution.md | 2 +- .../2-write-to-object-after-bind/task.md | 4 +- .../10-bind/3-second-bind/solution.md | 4 +- .../10-bind/3-second-bind/task.md | 6 +-- .../solution.md | 2 +- .../4-function-property-after-bind/task.md | 4 +- .../10-bind/5-question-use-bind/solution.md | 4 +- .../10-bind/5-question-use-bind/task.md | 2 +- .../10-bind/6-ask-partial/solution.md | 2 +- .../10-bind/6-ask-partial/task.md | 4 +- 1-js/06-advanced-functions/10-bind/article.md | 54 +++++++++---------- 11 files changed, 44 insertions(+), 44 deletions(-) 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 b349d5314..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 @@ -13,6 +13,6 @@ let user = { user.g(); ``` -Контекст прив'язаної функції жорстко-фіксований. Немає способу змінити це в подальшому. +Контекст прив’язаної функції жорстко-фіксований. Немає способу змінити це в подальшому. Так чином в той час як ми запускаємо `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 1fd4942db..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 @@ -1,8 +1,8 @@ -важливість: 5 +importance: 5 --- -# Прив'язана функція як метод +# Прив’язана функція як метод Що виведе функція? 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 dacb90668..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 @@ -10,6 +10,6 @@ f = f.bind( {name: "Іван"} ).bind( {name: "Христя"} ); f(); // Іван ``` -Екзотичний об'єкт [прив'язаної функції](https://tc39.github.io/ecma262/#sec-bound-function-exotic-objects) повертається від `f.bind(...)`, що запам'ятовує контекст (та аргументи, якщо передані) тільки під час створення. +Екзотичний об’єкт [прив’язаної функції](https://tc39.github.io/ecma262/#sec-bound-function-exotic-objects) повертається від `f.bind(...)`, що запам’ятовує контекст (та аргументи, якщо передані) тільки під час створення. -Функція не може бути переприв'язана. +Функція не може бути переприв’язана. 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 06e6d2f5d..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 @@ -1,10 +1,10 @@ -важливість: 5 +importance: 5 --- -# Друга прив'язка +# Друга прив’язка -Чи можемо ми змінити `this` за допомогою додаткового прив'язування? +Чи можемо ми змінити `this` за допомогою додаткового прив’язування? Який результат буде виведено? 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 5aadf02e9..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 @@ Відповідь: `undefined`. -Результатом `bind` є інший об'єкт. Він не містить властивість `test`. +Результатом `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 d81ac049f..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 @@ -1,8 +1,8 @@ -важливість: 5 +importance: 5 --- -# Властивість функції після прив'язки +# Властивість функції після прив’язки Функції присвоєна властивість зі значенням. Чи зміниться вона після `bind`? Чому? 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 b0f33e437..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,9 +1,9 @@ -Помилка виникає тому що `askPassword` отримує функції `loginOk/loginFail` без об'єкту. +Помилка виникає тому що `askPassword` отримує функції `loginOk/loginFail` без об’єкту. Коли вона викликає їх, їх контекст втрачено `this=undefined`. -Спробуємо використати `bind`, щоб прив'язати контекст: +Спробуємо використати `bind`, щоб прив’язати контекст: ```js run function askPassword(ok, fail) { 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 2945bc806..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 @@ -1,4 +1,4 @@ -важливість: 5 +importance: 5 --- 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 ddb3a2cbc..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,6 +1,6 @@ -1. Або використовуйте стрілкову функцію як функцію обгортку для короткого запису: +1. Або використовуйте стрілкову функцію як функцію-обгортку для короткого запису: ```js askPassword(() => user.login(true), () => user.login(false)); 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 5c09780fd..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 @@ -1,4 +1,4 @@ -важливість: 5 +importance: 5 --- @@ -6,7 +6,7 @@ Задача трохи складніша ніж . -Об'єкт `user` був змінений. Тепер замість двох функцій `loginOk/loginFail`, він має одну функцію `user.login(true/false)`. +Об’єкт `user` був змінений. Тепер замість двох функцій `loginOk/loginFail`, він має одну функцію `user.login(true/false)`. Що ми маємо передати `askPassword` в коді нижче, щоб вона викликала `user.login(true)` при `ok` та `user.login(false)` при `fail`? diff --git a/1-js/06-advanced-functions/10-bind/article.md b/1-js/06-advanced-functions/10-bind/article.md index 4e45705a9..561b4a2cb 100644 --- a/1-js/06-advanced-functions/10-bind/article.md +++ b/1-js/06-advanced-functions/10-bind/article.md @@ -3,15 +3,15 @@ libs: --- -# Прив'язка контексту до функції +# Прив’язка контексту до функції -Передаючи методи об'єкту в якості колбеків, наприклад в `setTimeout`, існує відома проблема: "втрата `this`". +Передаючи методи об’єкту в якості колбеків, наприклад в `setTimeout`, існує відома проблема: "втрата `this`". В цьому розділі ми розглянемо способи як це можливо виправити. ## Втрата "this" -Ми вже розглядали приклади втрати `this`. Якщо метод передавався окремо від об'єкта -- `this` втрачається. +Ми вже розглядали приклади втрати `this`. Якщо метод передавався окремо від об’єкта -- `this` втрачається. В прикладі наведено як це відбувається з `setTimeout`: @@ -30,16 +30,16 @@ setTimeout(user.sayHi, 1000); // Привіт, undefined! Як ми можемо спостерігати, модальне вікно браузера відображає не "Іван" як `this.firstName`, а `undefined`! -Це тому що `setTimeout` отримав функцію `user.sayHi` окремо від об'єкта. Останній рядок бути переписаний наступним чином: +Це тому що `setTimeout` отримав функцію `user.sayHi` окремо від об’єкта. Останній рядок бути переписаний наступним чином: ```js let f = user.sayHi; setTimeout(f, 1000); // втрата контексту об`єкта user ``` -Метод `setTimeout` в браузері трохи особливий: він встановлює `this=window` під час виклику функції (для Node.js, `this` стане об'єкт таймеру, але це не дуже важливо у цьому випадку). Таким чином для `this.firstName` метод намагається отримати `window.firstName`, що не існує. В інших схожих випадках, зазвичай `this` просто стає `undefined`. +Метод `setTimeout` в браузері трохи особливий: він встановлює `this=window` під час виклику функції (для Node.js, `this` стане об’єкт таймеру, але це не дуже важливо у цьому випадку). Таким чином для `this.firstName` метод намагається отримати `window.firstName`, що не існує. В інших схожих випадках, зазвичай `this` просто стає `undefined`. -Задача досить типова -- ми хочемо передати метод об'єкту деінде (в цьому випадку -- в планувальник) де він буде викликаний. Як бути впевненими в тому, що він буде викликаний з правильним контекстом? +Задача досить типова -- ми хочемо передати метод об’єкту деінде (в цьому випадку -- в планувальник) де він буде викликаний. Як бути впевненими в тому, що він буде викликаний з правильним контекстом? ## Рішення 1: обгортка @@ -68,9 +68,9 @@ setTimeout(function() { setTimeout(() => user.sayHi(), 1000); // Привіт, Іван! ``` -Виглядає чудово, але з'являється легка вразливість в структурі нашого коду. +Виглядає чудово, але з’являється легка вразливість в структурі нашого коду. -Що якщо перед спрацюванням `setTimeout` (з однією секундою затримки!) `user` змінить значення? Тоді, неочікувано, він викличе неправильний об'єкт! +Що якщо перед спрацюванням `setTimeout` (з однією секундою затримки!) `user` змінить значення? Тоді, неочікувано, він викличе неправильний об’єкт! ```js run @@ -93,7 +93,7 @@ user = { Наступне рішення гарантує, що така ситуація не трапиться. -## Рішення 2: прив'язка +## Рішення 2: прив’язка Функції надають нам вбудований метод [bind](mdn:js/Function/bind), що дозволяє зберегти правильний `this`. @@ -104,7 +104,7 @@ user = { let boundFunc = func.bind(context); ``` -Результатом `func.bind(context)` буде певний "екзотичний об'єкт", який може бути викликаний як функція та передає виклику `func` встановлений контекст `this=context`. +Результатом `func.bind(context)` буде певний "екзотичний об’єкт", який може бути викликаний як функція та передає виклику `func` встановлений контекст `this=context`. Іншими словами, виклик `boundFunc` це як виклик `func` з виправленим `this`. @@ -125,7 +125,7 @@ funcUser(); // Іван */!* ``` -Тут `func.bind(user)` як "прив'язаний варіант" функції `func`, з виправленим `this=user`. +Тут `func.bind(user)` як "прив’язаний варіант" функції `func`, з виправленим `this=user`. Всі аргументи передаються початковій функції `func` "як є", наприклад: @@ -138,7 +138,7 @@ function func(phrase) { alert(phrase + ', ' + this.firstName); } -// прив'язка до user +// прив’язка до user let funcUser = func.bind(user); *!* @@ -146,7 +146,7 @@ funcUser("Привіт"); // Привіт, Іван (переданий аргу */!* ``` -Тепер спробуємо з методом об'єкту: +Тепер спробуємо з методом об’єкту: ```js run @@ -161,19 +161,19 @@ let user = { let sayHi = user.sayHi.bind(user); // (*) */!* -// можемо викликати без об'єкту +// можемо викликати без об’єкту sayHi(); // Привіт, Іван! setTimeout(sayHi, 1000); // Привіт, Іван! // навіть якщо значення user зміниться впродовж 1 секунди -// sayHi використовує прив'язане значення, яке посилається на старий об'єкт user +// sayHi використовує прив’язане значення, яке посилається на старий об’єкт user user = { sayHi() { alert("Інший user в setTimeout!"); } }; ``` -В строчці `(*)` ми взяли метод `user.sayHi` та прив'язали його до `user`. `sayHi` є "прив'язаною" функцією, що може бути викликана окремо або передана до `setTimeout` -- не важливо, контекст буде правильний. +В строчці `(*)` ми взяли метод `user.sayHi` та прив’язали його до `user`. `sayHi` є "прив’язаною" функцією, що може бути викликана окремо або передана до `setTimeout` -- не важливо, контекст буде правильний. В цьому прикладі ми можемо бачити що аргументи передані "як є", тільки `this` виправлено за допомогою `bind`: @@ -192,7 +192,7 @@ say("Бувай"); // Бувай, Іван ("Бувай" передане фун ``` ````smart header="Зручний метод: `bindAll`" -Якщо об'єкт містить багато методів та ми плануємо активно їх передавати, тоді ми можемо прив'язати їх всіх за допомогою циклу: +Якщо об’єкт містить багато методів та ми плануємо активно їх передавати, тоді ми можемо прив’язати їх всіх за допомогою циклу: ```js for (let key in user) { @@ -202,14 +202,14 @@ for (let key in user) { } ``` -JavaScript бібліотеки також пропонуються функції для зручної масової прив'язки, наприклад [_.bindAll(object, methodNames)](http://lodash.com/docs#bindAll) в бібліотеці lodash. +JavaScript бібліотеки також пропонуються функції для зручної масової прив’язки, наприклад [_.bindAll(object, methodNames)](http://lodash.com/docs#bindAll) в бібліотеці lodash. ```` ## Часткове застосування -До цього моменту ми говорили тільки про прив'язку `this`. Зробимо крок далі. +До цього моменту ми говорили тільки про прив’язку `this`. Зробимо крок далі. -Ми можемо прив'язати не тільки `this`, а також аргументи. Це робиться рідко, проте може бути інколи дуже зручним. +Ми можемо прив’язати не тільки `this`, а також аргументи. Це робиться рідко, проте може бути інколи дуже зручним. Повний синтаксис `bind`: @@ -217,7 +217,7 @@ JavaScript бібліотеки також пропонуються функці let bound = func.bind(context, [arg1], [arg2], ...); ``` -Це дозволяє прив'язати context як `this` та початкові аргументи функції. +Це дозволяє прив’язати context як `this` та початкові аргументи функції. Наприклад, ми маємо функцію множення `mul(a, b)`: @@ -267,19 +267,19 @@ alert( triple(5) ); // = mul(3, 5) = 15 Чому ми використовуємо часткове застосування? -Перевагою цього є те, що ми можемо створити незалежну функцію з читабельним ім'ям (`double`, `triple`). Ми можемо використовувати її та не передавати перший аргумент кожен раз, оскільки це замість нас виконує `bind`. +Перевагою цього є те, що ми можемо створити незалежну функцію з читабельним ім’ям (`double`, `triple`). Ми можемо використовувати її та не передавати перший аргумент кожен раз, оскільки це замість нас виконує `bind`. В інших випадках, часткове застосування є корисним, коли ми маємо дуже загальну функцію та хочемо менш універсальний її варіант для зручності. -Наприклад, у нас є функція `send(from, to, text)`. Тоді, в середині об'єкту `user` ми можемо захотіти використати її частковий варіант: `sendTo(to, text)`, яка відправляє текст від поточного користувача. +Наприклад, у нас є функція `send(from, to, text)`. Тоді, в середині об’єкту `user` ми можемо захотіти використати її частковий варіант: `sendTo(to, text)`, яка відправляє текст від поточного користувача. ## Використання часткового застосування без контексту -Що якщо ми хочемо виправити деякі аргументи, але не контекст `this`? Наприклад, для методу об'єкта. +Що якщо ми хочемо виправити деякі аргументи, але не контекст `this`? Наприклад, для методу об’єкта. Вбудований метод `bind` не дозволяє цього. Ми можемо просто опустити контекст та перейти до аргументів. -На щастя, функція `partial` для прив'язування тільки аргументів може бути реалізована дуже просто. +На щастя, функція `partial` для прив’язування тільки аргументів може бути реалізована дуже просто. Як тут: @@ -319,9 +319,9 @@ user.sayNow("Привіт"); ## Висновок -Метод `func.bind(context, ...args)` повертає a "прив'язаний варіант" функції `func` який виправляє контекст `this` та аргументи, якщо вони передані. +Метод `func.bind(context, ...args)` повертає a "прив’язаний варіант" функції `func` який виправляє контекст `this` та аргументи, якщо вони передані. -Зазвичай ми застосовуємо `bind`, щоб виправити `this` для методу об'єкта та передати його деінде. Наприклад, в `setTimeout`. +Зазвичай ми застосовуємо `bind`, щоб виправити `this` для методу об’єкта та передати його деінде. Наприклад, в `setTimeout`. Коли ми виправляємо деякі аргументи існуючої функції, в результаті ми отримуємо (менш універсальну) функцію, яка називається *частково застосованою* або *частковою*. From cf9db4e53df29d2c32d4f97205cecdb474fc2b18 Mon Sep 17 00:00:00 2001 From: Taras Date: Thu, 30 Sep 2021 20:57:36 +0300 Subject: [PATCH 7/8] Update 1-js/06-advanced-functions/10-bind/article.md --- 1-js/06-advanced-functions/10-bind/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/10-bind/article.md b/1-js/06-advanced-functions/10-bind/article.md index 561b4a2cb..e5783b1f3 100644 --- a/1-js/06-advanced-functions/10-bind/article.md +++ b/1-js/06-advanced-functions/10-bind/article.md @@ -34,7 +34,7 @@ setTimeout(user.sayHi, 1000); // Привіт, undefined! ```js let f = user.sayHi; -setTimeout(f, 1000); // втрата контексту об`єкта user +setTimeout(f, 1000); // втрата контексту об’єкта user ``` Метод `setTimeout` в браузері трохи особливий: він встановлює `this=window` під час виклику функції (для Node.js, `this` стане об’єкт таймеру, але це не дуже важливо у цьому випадку). Таким чином для `this.firstName` метод намагається отримати `window.firstName`, що не існує. В інших схожих випадках, зазвичай `this` просто стає `undefined`. From c6870e33d2c4c593ca771a8cc3f0020768d96154 Mon Sep 17 00:00:00 2001 From: Taras Date: Thu, 30 Sep 2021 20:59:44 +0300 Subject: [PATCH 8/8] Update 1-js/06-advanced-functions/10-bind/article.md --- 1-js/06-advanced-functions/10-bind/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/06-advanced-functions/10-bind/article.md b/1-js/06-advanced-functions/10-bind/article.md index e5783b1f3..0eb6fd754 100644 --- a/1-js/06-advanced-functions/10-bind/article.md +++ b/1-js/06-advanced-functions/10-bind/article.md @@ -317,7 +317,7 @@ user.sayNow("Привіт"); Також існує реалізація [_.partial](https://lodash.com/docs#partial) в бібліотеці lodash. -## Висновок +## Підсумки Метод `func.bind(context, ...args)` повертає a "прив’язаний варіант" функції `func` який виправляє контекст `this` та аргументи, якщо вони передані. pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy