Прив'язка контексту (this) до функції в javascript і часткове застосування функцій

Розглянемо простий об'єкт, який містить властивість x і метод f. який виводить в консоль значення this.x

Як я зазначав у попередньому пості. при виклику object.f () в консолі буде виведено число 3. Припустимо тепер, що нам потрібно вивести дане число через 1 секунду.

Кожен раз використовувати функцію обгортку - незручно. Потрібен спосіб прив'язати контекст функції, так, щоб this всередині функції object.f завжди посилався на object

1. jQuery.proxy

Якщо нам потрібно вказати кілька разів однаковий callback, то замість дублювання

краще винести результат роботи $ .proxy в окрему змінну

Звернемо тепер увагу на те, що ми двічі вказали object всередині $ .proxy (перший раз метод об'єкта - object.f. Другий - передання контекст - object). Може бути є можливість уникнути дублювання? Відповідь - так. Для таких випадків в $ .proxy додана альтернативна можливість передачі параметрів - першим параметром повинен бути об'єкт, а другим - назва його методу. приклад:

Зверніть увагу на те, що назва методу передається у вигляді рядка.

2. Function.prototype.bind

Сумісність з браузерами

Firefox (Gecko): 4.0 (2)
Chrome: 7
Internet Explorer: 9
Opera: 11.60
Safari: 5.1.4

Емуляція Function.prototype.bind з Mozilla Developer Network

Function.prototype.bind має 2 призначення - статична прив'язка контексту до функції і часткове застосування функції.
По суті bind створює нову функцію, яка викликає func в контексті context. Якщо вказані аргументи arg1, arg2 ... - вони будуть додані до кожного виклику нової функції, причому встануть перед тими, які вказані при виклику нової функції.

2.1. прив'язка контексту

Використовувати bind для прив'язки контексту дуже просто, достатньо просто розглянути приклад:

Таким чином приклад зі вступу можна записати в наступному вигляді:

2.2. Часткове застосування функцій

Для спрощення розглянемо відразу приклад використання bind для часткового застосування функцій

Як видно з прикладу - суть часткового застосування функцій проста - створення нової функції зі зменшеною кількістю аргументів, за рахунок «фіксації» перших аргументів за допомогою функції bind.
На цьому можна було б закінчити статтю, але ... Функції, отримані з використанням методу bind мають деякі особливості в поведінці

2.3. особливості bind

Перш ніж розібрати - я перерахую основні особливості bind відповідно до стандарту.

2.3.1. внутрішні властивостей

У об'єктів Function, створених за допомогою Function.prototype.bind, відсутня властивість prototype або внутрішні властивості [[Code]], [[FormalParameters]] і [[Scope]].

Це обмеження відрізняє built-in реалізацію bind від вручну певних методів (наприклад, варіант з MDN)

2.3.2. call і apply

Поведінка методів call і apply відрізняється від стандартного поведінки для функцій, а саме:

У коді видно, що thisValue не використовується ніде. Таким чином підмінити контекст виклику для функцій отриманих за допомогою Function.prototype.bind з використанням call і apply - не можна!

2.3.3. У конструкторі

У конструкторі this посилається на новий (створюваний) об'єкт. Інакше кажучи, контекст заданий за допомогою bind просто ігнорується. Конструктор викликає звичайний [[Call]] вихідної функції.
Важливо! Якщо в конструкторі відсутня return this. то повертається значення в загальному випадку не визначено!

Розбір прикладу

висновок

У даній статті я постарався описати основні методи прив'язування контексту до функцій, а також описав деякі особливості в роботі Function.prototype.bind, при цьому я намагався залишити тільки важливі деталі (з моєї точки зору).
Якщо ви помітили помилки / неточності або хочете щось уточнити / додати - напишіть в ЛС, поправлю