← Назад к вопросам

Можно ли оиспользовать Bind или Apply на стрелочной функции?

2.2 Middle🔥 271 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Можно ли использовать bind или apply на стрелочной функции

Ответ: Технически можно, но это не сработает. Стрелочные функции имеют лексическую привязку this, которая установлена в момент определения функции и не может быть переопределена методами bind(), apply() или call().

Почему это не работает

Стрелочные функции, в отличие от обычных функций, не имеют собственного контекста this. Вместо этого они используют this из окружающей области видимости (enclosing scope).

const arrowFunc = () => {
  console.log(this);
};

const obj = { name: 'Object' };

// Попытка привязать другой контекст
arrowFunc.bind(obj)(); // window (или global) — контекст не изменился!
arrowFunc.call(obj);   // window (или global) — контекст не изменился!
arrowFunc.apply(obj); // window (или global) — контекст не изменился!

Практический пример

// Обычная функция (работает с bind/call/apply)
function regularFunc() {
  console.log(this.name);
}

const person = { name: 'Иван' };
regularFunc.call(person); // "Иван" — работает!

// Стрелочная функция (НЕ работает с bind/call/apply)
const arrowFunc = () => {
  console.log(this.name);
};

arrowFunc.call(person); // undefined — не работает!

Контекст strelochной функции

Так как стрелочная функция принимает this из окружающей области, контекст зависит от того, где она определена:

const user = {
  name: 'Иван',
  
  // Обычный метод: this = user
  greet() {
    console.log(this.name);
  },
  
  // Стрелочная функция: this = глобальный контекст (window или global)
  greetArrow: () => {
    console.log(this); // window или global
  }
};

user.greet();      // "Иван"
user.greetArrow(); // window

Правильное использование внутри класса

class Calculator {
  value = 5;
  
  // Обычный метод
  addRegular(n) {
    return this.value + n; // this = экземпляр класса
  }
  
  // Стрелочная функция
  addArrow = (n) => {
    return this.value + n; // this = экземпляр класса (лексический)
  }
}

const calc = new Calculator();

// Обе работают, но по разным причинам
calc.addRegular(3); // 8
calc.addArrow(3);   // 8

// Проблема с обычным методом
const add = calc.addRegular;
add(3); // ОШИБКА: Cannot read property 'value' of undefined

// Стрелочная функция работает везде
const addArrow = calc.addArrow;
addArrow(3); // 8 — работает!

Сравнение bind/call/apply с разными функциями

function showThis() {
  console.log(this);
}

const arrow = () => {
  console.log(this);
};

const obj1 = { name: 'Object 1' };
const obj2 = { name: 'Object 2' };

// С обычной функцией
showThis.call(obj1); // { name: 'Object 1' }
showThis.call(obj2); // { name: 'Object 2' }

const boundShow = showThis.bind(obj1);
boundShow();         // { name: 'Object 1' }
boundShow.call(obj2); // { name: 'Object 1' } — call не переопределяет bind!

// Со стрелочной функцией
arrow.call(obj1);  // window (не изменяется)
arrow.call(obj2);  // window (не изменяется)

const boundArrow = arrow.bind(obj1);
boundArrow();      // window (не изменяется)

Почему методы возвращают undefined

const calculator = {
  value: 10,
  
  // Обычный метод
  multiply: function(n) {
    return this.value * n;
  },
  
  // Стрелочная функция
  divide: (n) => {
    return this.value / n; // this не определён
  }
};

calculator.multiply(5); // 50 — работает
calculator.divide(2);   // NaN — this.value = undefined

// Если попытаться привязать
const bindDivide = calculator.divide.bind(calculator);
bindDivide(2); // NaN — всё равно не работает!

Когда стрелочные функции полезны

1. В обработчиках событий React

class Button extends React.Component {
  handleClick = () => {
    // this = компонент, даже если передать это обработчику
    this.setState({ clicked: true });
  }
  
  render() {
    return <button onClick={this.handleClick}>Click</button>;
  }
}

2. В setTimeout/setInterval

const timer = {
  seconds: 0,
  
  start: function() {
    // Стрелочная функция сохраняет this
    setInterval(() => {
      this.seconds++;
      console.log(this.seconds);
    }, 1000);
  }
};

timer.start(); // Работает корректно

3. В обработчиках промисов

class DataFetcher {
  data = null;
  
  fetch() {
    fetch('/api/data')
      .then(response => response.json())
      // Стрелочная функция сохраняет this = компонент
      .then(data => {
        this.data = data;
      });
  }
}

Таблица сравнения

АспектОбычная функцияСтрелочная функция
Имеет собственный thisДаНет
bind() работаетДаНет
call() работаетДаНет
apply() работаетДаНет
Наследует this из контекстаНетДа
Лучше для методов классаНетДа
Лучше для обработчиковЗависитДа

Проверка

Можете проверить сами:

const globalThis = this; // Сохраняем глобальный контекст

const arrowFunc = () => {
  return this === globalThis; // true
};

const boundArrow = arrowFunc.bind({ name: 'Object' });
console.log(boundArrow()); // true — bind не работает!

Вывод

Bind, call и apply НЕ работают со стрелочными функциями потому что стрелочные функции используют лексическую привязку this из момента определения. Это одна из самых важных различий между обычными функциями и стрелочными функциями в JavaScript. Используйте:

  • Обычные функции когда нужен динамический this (методы объектов, конструкторы)
  • Стрелочные функции для обработчиков событий, callbacks и когда нужно сохранить this из внешней области