# 03.ii Bound Function

A **bound function** is a function bind with an object using `fn.bind(obj)` method. As a result of bind call we receive new function with a `this` bound to `obj` forever. `.bind()` makes a permanent context link and will always keep it.&#x20;

The original and bound functions share the same code and scope, but different contexts on execution. `this` is the first argument of `.bind()` when invoking a bound function.

`fun.bind(thisArg, [arg1, arg2, ...])`

* `thisArg` value to be passed as the this parameter to the target function when the bound function is called. The value is ignored if the bound function is constructed using the `new` operator.
* `[arg1, arg2, ...]` - arguments provided to the bound function when invoking the target function.

In general, `.bind` function is equals to following code:

```javascript
function bind(func, context) {
  return function() {
    return func.apply(context, arguments);
  };
}
```

Методы `call`/`apply` вызывают функцию с заданным контекстом и аргументами. А `bind` не вызывает функцию. Он только возвращает «обёртку», которую мы можем вызвать позже, и которая передаст вызов в исходную функцию, с привязанным контекстом.

## Use `bind` to carry function:

> **Карринг** (currying) или каррирование – термин функционального программирования, который означает создание новой функции путём фиксирования аргументов существующей.

При помощи `bind` удобно выполнять каррирование функции:

```javascript
function mul(a, b) {
  return a * b;
}
// double умножает только на два
var double = mul.bind(null, 2); // контекст фиксируем null, он не используется

double(3); // = mul(2, 3) = 6
double(4); // = mul(2, 4) = 8
double(5); // = mul(2, 5) = 10
```

Говорят, что `double` является *частичной функцией* (partial function) от `mul`.

## Decorate functions with `bind`

Через функцию `bind` и привязку контекста очень удобно делать функции-декораторы поверх других функций. Создадим декоратор, замеряющий время выполнения функции. Он будет называться `timingDecorator` и получать функцию вместе с «названием таймера», а возвращать — функцию-обёртку, которая измеряет время и прибавляет его в специальный объект `timer` по свойству-названию:

```javascript
const timers = {};

// прибавит время выполнения f к таймеру timers[timer]
function timingDecorator(f, timer) {
  return function() {
    const start = performance.now();

    const result = f.apply(this, arguments); // (*)

    if (!timers[timer]) timers[timer] = 0;
    timers[timer] += performance.now() - start;

    return result;
  };
}

// функция может быть произвольной, например такой:
function fibonacci(n) {
  return n > 2 ? fibonacci(n - 1) + fibonacci(n - 2) : 1;
}

// использование: завернём fibonacci в декоратор
fibonacci = timingDecorator(fibonacci, "fibo");

// неоднократные вызовы...
fibonacci(10); // 55
fibonacci(20); // 6765
// ...

// в любой момент можно получить общее количество времени на вызовы
alert(timers.fibo + "мс");
```

Декораторы можно не только повторно использовать, но и комбинировать!

Это кардинально повышает их выразительную силу. Декораторы можно рассматривать как своего рода возможности, которые можно «нацепить» на любую функцию. Можно один, а можно несколько.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://strctr.gitbook.io/programming/01-languages/javascript/01-language/c-functions/c1-functions/03.ii-bound-function.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
