Ключевое слово ‘this в Javascript является одним из наиболее часто неправильно понимаемых понятий, поскольку его поведение зависит от того, как и где оно было вызвано.

Ключевое слово this относится к текущему объекту / функции / методу, с которым они работают, и оно не свойственно Javascript, оно также доступно на других языках, но здесь, в Javascript, оно ведет себя иначе по сравнению с этими языками. В Javascript контекст this различается в зависимости от того, как вы вызываете, и от того, было ли оно выполнено в строгом или нестрогом режиме.

Браузер и Node.js:

В консоли браузера, если вы наберете «this», он распечатает объект окна для вас, а в node.js REPL, если вы введете это, он распечатает globalThis.

call (), apply () и bind ()

Как уже упоминалось, контекст ключевого слова «this» различается в зависимости от того, где и как он был назван. При вызове в строгом режиме контекст «this» не будет определен. Но вы можете установить контекст для «this», используя функции call (), apply () или bind ().

В приведенном выше примере функция foo () использует строгий режим, и поэтому значение this становится undefined и выдает ошибку, когда мы пытаемся получить доступ к свойству из него. Но если бы мы попробовали ту же функцию без 'use strict', тогда 'this' указывал бы на глобальный контекст, а 'this.name 'напечатал бы' Глобальное имя '.

Также, как вы могли видеть в следующей строке, мы создали объект (obj), а после этого, когда мы сделали foo.call (obj) и foo.apply (obj) мы получили результат 'bar', потому что обе функции call () и apply () устанавливают значение 'this 'во все, что мы передаем им в качестве первого аргумента.

Разница между call () и apply () заключается в том, что call () ожидает, что параметры будут переданы как отдельные аргументы, но в apply () аргументы предоставляются в виде массива.

call:
foo.call(obj, a, b);
apply:
foo.apply(obj, [a, b])

Есть еще один способ добиться того же, - .bind (), и разница между bind () и двумя другими заключается в том, что когда мы используем .bind (), он возвращает новую функцию, а не выполнить функцию сразу, как call () и apply ().

const bar = foo.bind(obj)
bar();

Функции и методы:

Когда функция определяется в рамках объекта или класса, она вызывается как метод. Хотя может показаться, что есть только синтаксические различия, но есть и некоторые поведенческие различия. Первый, с которого следует начать, - это поведение «this» внутри функции и метода.

  1. Внутри метода: «this» относится к текущему объекту / владельцу, которому принадлежит метод.
  2. Внутри функции: по умолчанию "this" указывает на глобальный объект. При вызове с использованием функции call (), apply () или bind () она обращается к любому аргументу, который мы им передаем. Когда функция вызывается как конструктор с использованием new, тогда this относится к новому экземпляру.

Метод:

Как вы могли видеть в первом случае, greet () - это метод внутри объекта, и когда мы вызываем greet, он возвращает «Я метод», потому что ' this 'внутри greet (method) относится к текущему объекту / владельцу, который находится здесь foo.

Функция:

Во втором случае bar () - это функция, и this не было установлено при вызове функции, поэтому this внутри нее указывает на глобальный объект, и поскольку постоянное сообщение было установлено в глобальном объекте, bar () печатает «Я - функция».

Функция стрелки:

Стрелочная функция является новым дополнением к семейству Javascript с момента выпуска ES6, и это сделало традиционные функции более понятными и легкими для визуализации, но в отличие от обычной функции стрелочная функция имеет другое поведение, похожее на «this».

Стрелочные функции имеют лексическую область видимости, и, следовательно, «this» внутри стрелочной функции указывает на ближайшую область видимости функции / метода.

Здесь foo - это объект с методом с именем fooMethod () и другим методом с именем arrowFunc (), который использует стрелочные функции ES6. Если вы видите результат в обоих случаях, «this.language» дал разные результаты.

В arrowFunc () this.language возвращает undefined, но в fooMethod () возвращается «JavaScript».

Как упоминалось ранее, стрелочная функция имеет лексическую область видимости, а 'this' указывает на ближайшую область видимости функции, здесь foo - это объект, а не функция, и нет других функций, обертывающих foo, поэтому 'this' указывает на глобальный объект, и мы не имеем Не устанавливаю какой-либо ключ в глобальном объекте как язык. поэтому arrowFunc () напечатало undefined, когда мы попытались ‘this.language’.

В то время как для fooMethod () «this» указывает на текущий рабочий объект (foo) и, таким образом, выводит «JavaScript». Теперь давайте попробуем тот же пример с функцией стрелки, объявленной внутри обычной функции.

arrowFunc (): здесь 'this' указывает на ближайшую область действия функции, которой является foo (), в которой 'this' указывает на глобальный объект, и мы добавили ключевой 'language' к 'this' foo (). Поэтому, когда мы пробуем использовать this.language в arrowFunc (), он выводит "JavaScript" - это просто.

«this» для нормальной работы определяется на основе следующих шагов:

  1. Если он был явно установлен с помощью call (), apply () или bind (), тогда значения, установленные в аргументе, используются как «this».
  2. Если функция вызывается как конструктор, она указывает на предоставленные новые значения экземпляра.
  3. Если явное значение не указано, по умолчанию используется глобальный объект.

«this» в JavaScript иногда может сбивать с толку, но это не так сложно, как ракетостроение, мы должны четко понимать, где и как мы его используем.

Удачного кодирования!