HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-02-26
1 <p>Стрелочные функции отличаются от обычных не только способом записи. Главное их отличие проявляется в том, как они работают с контекстом. Вкратце: контекст обычных функций зависит от места вызова, а контекст стрелочных функций - от того места, где они были определены.</p>
1 <p>Стрелочные функции отличаются от обычных не только способом записи. Главное их отличие проявляется в том, как они работают с контекстом. Вкратце: контекст обычных функций зависит от места вызова, а контекст стрелочных функций - от того места, где они были определены.</p>
2 <p>Рассмотрим несколько примеров. Самый простой случай - определение функции на уровне модуля. Здесь контекстом вызова будет сам модуль.</p>
2 <p>Рассмотрим несколько примеров. Самый простой случай - определение функции на уровне модуля. Здесь контекстом вызова будет сам модуль.</p>
3 <p><em>Примечание: примеры ниже приведены для Node.js. В браузере this по умолчанию будет содержать глобальный объект Window.</em></p>
3 <p><em>Примечание: примеры ниже приведены для Node.js. В браузере this по умолчанию будет содержать глобальный объект Window.</em></p>
4 <p>Здесь поведение функций не отличается, так как контекстом вызова у обеих функций является сам модуль, а в es6 this у модулей не определен. Теперь попробуем добавить эти функции в объект:</p>
4 <p>Здесь поведение функций не отличается, так как контекстом вызова у обеих функций является сам модуль, а в es6 this у модулей не определен. Теперь попробуем добавить эти функции в объект:</p>
5 <p>Обычная функция ожидаемо связалась с контекстом того объекта, на котором она вызвана. А вот в случае стрелочной функции такого не произошло. Почему? Стрелочная функция не имеет своего контекста, она связывается с лексическим окружением, то есть функцией, внутри которой определена стрелочная функция. Это очень важный момент. Именно функция верхнего уровня задаёт контекст стрелочной функции, а не что-то другое. И это поведение нельзя изменить с помощью функций call или bind.</p>
5 <p>Обычная функция ожидаемо связалась с контекстом того объекта, на котором она вызвана. А вот в случае стрелочной функции такого не произошло. Почему? Стрелочная функция не имеет своего контекста, она связывается с лексическим окружением, то есть функцией, внутри которой определена стрелочная функция. Это очень важный момент. Именно функция верхнего уровня задаёт контекст стрелочной функции, а не что-то другое. И это поведение нельзя изменить с помощью функций call или bind.</p>
6 <p>Теперь определим стрелочную функцию внутри какого-нибудь объекта и попробуем вызвать:</p>
6 <p>Теперь определим стрелочную функцию внутри какого-нибудь объекта и попробуем вызвать:</p>
7 <p>Здесь мы видим точно такую же картину. Несмотря на то, что стрелочная функция описывается внутри объекта и вызывается из этого же объекта, контекст все равно связан с местом определения функции (лексическим окружением) - а это сам модуль.</p>
7 <p>Здесь мы видим точно такую же картину. Несмотря на то, что стрелочная функция описывается внутри объекта и вызывается из этого же объекта, контекст все равно связан с местом определения функции (лексическим окружением) - а это сам модуль.</p>
8 <p>Теперь попробуем определить стрелочную функцию внутри другой функции:</p>
8 <p>Теперь попробуем определить стрелочную функцию внутри другой функции:</p>
9 <p>Кажется, что у стрелочной функции появился this, но этот контекст не принадлежит функции, она заимствовала его у внешней функции print. Чтобы лучше это понять, представьте, как вызывается стрелочная функция внутри forEach. Она вызывается напрямую, а не из объекта. Обычные функции в такой ситуации создают свой собственный контекст, а стрелочные нет. Они берут контекст из того места, где были определены. Стрелочная функция определена в функции print, поэтому берёт контекст функции print.</p>
9 <p>Кажется, что у стрелочной функции появился this, но этот контекст не принадлежит функции, она заимствовала его у внешней функции print. Чтобы лучше это понять, представьте, как вызывается стрелочная функция внутри forEach. Она вызывается напрямую, а не из объекта. Обычные функции в такой ситуации создают свой собственный контекст, а стрелочные нет. Они берут контекст из того места, где были определены. Стрелочная функция определена в функции print, поэтому берёт контекст функции print.</p>
10 <p>Точно такой же код с обычной функцией уже не заработает:</p>
10 <p>Точно такой же код с обычной функцией уже не заработает:</p>
11 <p>Это происходит именно потому, что функция вызывается как обычная функция, а не метод. В таком случае ее контекст будет равен глобальному контексту. Обычно этот контекст равен undefined, а значит this.items вызовет ошибку.</p>
11 <p>Это происходит именно потому, что функция вызывается как обычная функция, а не метод. В таком случае ее контекст будет равен глобальному контексту. Обычно этот контекст равен undefined, а значит this.items вызовет ошибку.</p>
12 <p>Где все это может понадобиться? В подавляющем большинстве ситуаций нам вообще не нужен this внутри стрелочной функции. Всегда лучше работать с данными, переданными явно. Однако есть несколько примеров, где эта особенность стрелочных функций помогает упростить код. К таким примерам относятся ситуации, где внутри метода объекта вызывается функция высшего порядка, куда передается стрелочная функция, работающая с this. Эта ситуация аналогичная коду выше.</p>
12 <p>Где все это может понадобиться? В подавляющем большинстве ситуаций нам вообще не нужен this внутри стрелочной функции. Всегда лучше работать с данными, переданными явно. Однако есть несколько примеров, где эта особенность стрелочных функций помогает упростить код. К таким примерам относятся ситуации, где внутри метода объекта вызывается функция высшего порядка, куда передается стрелочная функция, работающая с this. Эта ситуация аналогичная коду выше.</p>