Почему в методе `bind` можно передать только один контекст?

Как устроена логика метода `bind` в JavaScript, почему он принимает только первый контекст, а последующие игнорирует, даже если мы цепляем их друг за другом?
Для чего предназначен этот механизм и как правильно использовать его для изменения контекста функции в JavaScript?
  • 26 апреля 2024 г. 15:30
Ответы на вопрос 3
Метод `bind` в JavaScript применяется для создания новой функции с привязанным контекстом, который будет использоваться при вызове этой функции. Когда мы передаем один контекст в метод `bind`, он создает новую функцию, которая будет вызываться именно в этом контексте.

Логика метода `bind` заключается в том, что он принимает первый параметр как контекст, а все последующие параметры будут передаваться как аргументы при вызове созданной функции. Поэтому даже если мы передаем несколько контекстов последовательно, только первый будет учитываться.

Например, если у нас есть функция `sayHello`:

```javascript
function sayHello() {
  console.log(`Hello, ${this.name}`);
}
```
И мы хотим вызвать эту функцию в контексте объекта `person`:

```javascript
const person = {
  name: 'Alice'
};

const sayHelloToAlice = sayHello.bind(person);
sayHelloToAlice(); // Выведет "Hello, Alice"
```
В данном примере мы создаем новую функцию `sayHelloToAlice`, которая будет вызываться в контексте объекта `person`.

Чтобы изменить контекст функции на другой, например на объект `anotherPerson`, мы должны создать новую связанную функцию для этого объекта:

```javascript
const anotherPerson = {
  name: 'Bob'
};

const sayHelloToBob = sayHello.bind(anotherPerson);
sayHelloToBob(); // Выведет "Hello, Bob"
```

Таким образом, чтобы изменить контекст функции, нужно использовать метод `bind` с одним контекстом, который будет привязан к новой функции. Каждый раз, когда нам нужно изменить контекст функции, мы должны вызывать метод `bind` с новым контекстом.
Просто его так задумали. "Кто первый встал, того и тапки". Могли сделать по-другому, но сделали - так.
Метод bind возвращает новую функцию, которая уже игнорирует свой контекст и передаёт тот, который запомнила. 
Если в коде, то это примерно так работает:
Function.prototype.bind = function bind(ctx, ...args) {
    const originalFunction = this;
    return function (...args2) {
        return originalFunction.apply(ctx, args.concat(args2));
    };
}
Как видите, возвращаемая функция уже никак не использует свой this.
Соответственно второй вызов bind его будет передавать в пустоту, однако может добавить аргументы.
Похожие вопросы