В чем отличие контекста в строгом режиме и без него в JavaScript
Что проверяют
Понимаете ли вы, что this определяется способом вызова функции, а строгий режим меняет только поведение по умолчанию. Следом почти всегда просят объяснить потерю контекста у метода, переданного как колбэк, и что меняют стрелочные функции.
Как отвечать
Главные различия:
- обычный вызов
f(): в нестрогом режимеthisэто глобальный объект (windowв браузере,globalThisв общем случае), в строгомundefined; call,apply,bindс примитивом,nullилиundefined: в нестрогом режиме примитив оборачивается в объект, аnullиundefinedзаменяются глобальным объектом. В строгом значение передаётся как есть;- вызов метода
obj.f(), вызов черезnew, обработчик вaddEventListener: в обоих режимах работают одинаково. Это объект, новый экземпляр и элемент соответственно; - стрелочные функции: своего
thisне имеют и берут его из окружающей области, режим на них не влияет.
Как включается режим: директива 'use strict' в самом начале скрипта или тела функции. ES-модули и тела классов строгие всегда, поэтому в современном фронтенде с import/export и сборкой через Vite или webpack вы почти всегда пишете в строгом режиме, даже без директивы.
Практическое следствие для React: метод классового компонента, переданный в onClick без привязки, получает this === undefined и падает с TypeError. Лечится bind в конструкторе или стрелочным полем класса.
Строгий режим меняет и другое: присваивание необъявленной переменной бросает ReferenceError, запись в свойство только для чтения бросает TypeError.
Где спотыкаются
Ставят 'use strict' посреди файла, как в популярных примерах. Директива работает только первой инструкцией, иначе это обычная строка, и режим не включается.
Говорят, что в строгом режиме this на верхнем уровне скрипта равен undefined. В обычном скрипте там по-прежнему window, а undefined будет на верхнем уровне ES-модуля.
Путают потерю контекста с замыканием и лечат её, сохраняя this в переменную где попало. Сначала нужно понять, как функция вызывается, а потом выбирать bind или стрелку.