Этот

Если вы изучаете JavaScript, вы, вероятно, несколько раз сталкивались с «этим», обычно с минимальным объяснением, за которым следует что-то вроде «не беспокойтесь о том, как это работает, позже это станет более понятным». Ну, это позже, так что же это?

Это: свойство контекста выполнения (глобального, функционального или eval), которое в нестрогом режиме всегда является ссылкой на объект, а в строгом режиме может принимать любое значение. -MDN документы

Чтобы понять, что это значит, вы должны понимать, как JavaScript выполняет код. Давайте начнем с базового понимания this, различных примеров this и ручной установки значения this, затем мы перейдем к контекстам выполнения и, наконец, к подъему.

Более простой способ объяснить цитату MDN — сказать, что значение this для функции — это контекст, в котором она вызывается, для прослушивателя событий — это элемент, к которому присоединен слушатель, а для метода — это объект, который владеет методом.

function returnThis () {
  return this
}

В этом примере вызов returnThis вернет объект окна (в браузере), поскольку функция объявлена ​​в глобальном контексте и, таким образом, принадлежит глобальному объекту, что означает, что она не объявлена ​​в другой функции или объекте.

class WhatIsThis {
  returnThis () {
    return this
  }
}
let test = new WhatIsThis

В этом примере test.returnThis() возвращает экземпляр WhatIsThis, на который ссылается «test», поскольку WhatIsThis является объектом, которому принадлежит метод returnThis().

function log () {console.log(this)}
const button = document.querySelector('button');
buttons.addEventListener('click', log);

Для этого примера представьте, что у нас есть веб-страница, содержащая одну кнопку с прослушивателем событий, который вызывает функцию журнала при срабатывании. Вы попробуете это с помощью этого codepen, который я сделал, вы увидите, что элемент DOM кнопки регистрируется в консоли при нажатии кнопки. Это связано с тем, что значением this в прослушивателях событий является элемент, к которому присоединен прослушиватель, однако, если бы мы запускали log() непосредственно в консоли без использования прослушивателя событий, он вернул бы объект окна. Это связано с тем, что значение this внутри функции определяется контекстом, в котором она вызывается, а это означает, что когда log() вызывается в прослушивателе событий, значение this внутри log является элементом кнопки DOM!

function external () {
  return this.name
}
let person = {
  name: "Sam",
  age: 27
}
let sam = external.bind(person)
console.log(sam())

Этот пример кода показывает ручную установку значения this с помощью .bind(), использование a.bind(b) вернет новую функцию с тем же телом и областью действия, что и a, но где это то же самое, что и в b. В этом примере кода мы определяем функцию external, которая возвращает this.name. Если бы external вызывалась как есть, она вернула бы пустую строку. Мы также создали объект «человек» с двумя атрибутами: имя и возраст. Затем мы используем bind() для создания новой функции с именем sam, используя this человека с внешней функцией. вызвав sam(), вы увидите, что возвращается атрибут name объекта person.

Контексты выполнения

Когда вы запускаете скрипт, вы можете подумать, что движок JavaScript выполняет ваш код построчно, выполняя код по ходу дела, однако это неверно, поскольку движок JavaScript работает в два этапа: создание и выполнение.

const myName = 'Sam';
function greet (name) {
  return `Hello ${name}`;	
}
const greetSam = greet(myName);
console.log(greetSam)

Мы рассмотрим этот код шаг за шагом так же, как это делает движок JavaScript. Когда вы выполняете этот сценарий в первый раз, JavaScript создает первый контекст выполнения, глобальный контекст выполнения и привязывает его к ключевому слову this, он также выделяет память для переменных myName и welcomeSam и объявления функции для приветствия (), однако он сохраняет переменная как неопределенная.

После этапа создания JavaScript переходит к этапу выполнения, где он присваивает значения переменным и выполняет вызовы функций. Каждый раз, когда JavaScript достигает вызова функции, он создает новый контекст выполнения для функции, снова подвергаясь фазе создания и выполнения для каждого нового контекста, возвращая результирующее значение в глобальный контекст выполнения, который продолжает выполнять оставшийся код. Чтобы продолжить наш пример после перехода к фазе выполнения, движок JavaScript будет:

  1. присвойте строку «Sam» переменной myName.
  2. создать новый контекст выполнения для вызова приветствия () в приветствии Сэма
  3. выполнить контекст для вызова приветствия()
  4. вернуть результат приветствия() в глобальный контекст выполнения.
  5. присвоить возвращаемое значение переменнойgreetSam
  6. записывать значение welcomeSam в консоль

Подъем

Подъем — это способ концептуализировать то, как JavaScript создает контексты выполнения, влияет на то, когда переменные и функции доступны во время выполнения кода. То, как на этапе создания все переменные и функции помещаются в память перед выполнением кода, создает впечатление, что все ваши объявления переменных и функций «подняты» в начало файла, например:

greetUser()
function greetUser () {
  console.log('Hello')
}

В этом примере функция приветствия пользователя() вызывается еще до того, как она будет написана, и вы интуитивно ожидаете, что это приведет к ошибке, однако на этапе создания объявление приветствия пользователя было поднято до того, как вызов был выполнен.

Поднимаются только объявления:

console.log(x) // Undefined
var x;         // Declaration
// let & const not hoisted, cannot reference before init
// const must have initializer in declaration
console.log(y) // ReferenceError
let y = 6;     // Declaration and Initialization NO HOIST

С базовым пониманием того, как JavaScript выполняет код, подъем должен быть довольно простой концепцией.

Вывод

Надеюсь, этот пост помог кому-то лучше понять выполнение кода This, Hoisting и JavaScript в целом, я знаю, что он определенно помог мне.

Если вам понравилось мое письмо, не стесняйтесь проверить мой веб-сайт и связаться со мной в LinkedIn.

Дополнительные материалы на plainenglish.io