Асинхронный код, принуждение и ключевое слово this-keyword

Я знаю - шутки программистов не такие уж смешные.

Тем не менее они могут помочь передать концепции.
Вот 3 мема JavaScript, которые затрагивают важные концепции!

1. "this" в JavaScript

Ключевое слово this существует во всех объектно-ориентированных языках программирования. В JavaScript мы можем программировать объектно-ориентированные программы, но «this» иногда ведет себя немного необычно. Вот пример:

У нас есть класс, в котором мы хотим вывести марку нашего автомобиля.
Конструктор следит за тем, чтобы атрибут «brand» был доступен в классе.

Если мы запустим такой код, все заработает. Но теперь мы хотим подождать одну секунду перед выводом - это несложно, просто поместите setTimeout в метод nameBrand ().

nameBrand() {
  setTimeout(function() {
    console.log(this.brand)
  }, 1000)
}

Ошибка. Если мы запустим такой код, this.brand будет неопределенным.

Почему? Потому что классическая функция, которую мы используем в качестве обратного вызова, связывает this с setTimeout. Правильно, для классической JS-функции это так, но не для стрелочных функций!

Если мы изменим метод nameBrand () только минимально, все будет работать так, как ожидалось:

nameBrand() {
  setTimeout(() => {
    console.log(this.brand)
  }, 1000)
}

Обычные функции и функции со стрелками обрабатывают «this» по-разному. Тот факт, что есть только два типа функций, необычен для многих программистов.

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



Это лишь одна из сбивающих с толку ситуаций, которые могут возникнуть при работе с этим.

2. Синхронный или асинхронный?

Если быть точным, JavaScript - это синхронный язык программирования.
Но что это вообще значит?

Синхронная программа выполняется поэтапно. Компьютер выполняет одну задачу за раз. Выполнение продолжается только после завершения задачи.

Асинхронная программа также выполняется шаг за шагом, но не обязательно ждать. Чтобы задача B была выполнена, задача A не должна быть завершена - вместо этого B продолжает обрабатываться в фоновом режиме.

Итак, JavaScript на самом деле синхронный - этот шаблон идеально подходит для понимания при его выполнении. Но это также имеет большой недостаток: потоки в нашей программе блокируются, а часто мы этого не хотим. Однако в JS некоторые обратные вызовы допускают асинхронный код, например, setTimeout, и именно это может привести к конфискации.

Для этого давайте посмотрим, как мы будем рассчитывать время выполнения программы на Python:

import time
time.sleep(1)
print("after 1 second")
print("Hello!")

Результат на консоли: через 1 секунду, Hello!
Однако до того, как оба будут выведены, проходит секунда. Таким образом, функция time.sleep прерывает выполнение.

Если мы хотим реализовать тот же код в JS, первое, что приходит на ум, вероятно, следующее:

setTimeout(() => {
  console.log("after 1 sec")
}, 1000)
console.log("Hello!")

Но вот что происходит: Здравствуйте! через 1 секунду

Правильно, setTimeout не прерывает все выполнение программы. То, что здесь происходит, является асинхронным. Компьютер распознает функцию setTimeout, но переходит к console.log - верхний код выполняется в фоновом режиме.

Это может сбивать с толку, особенно для тех, кто работает с такими языками, как Python.

3. Принуждение

JavaScript считается довольно случайным, но, конечно, это не так. За всем странным поведением скрывается логика.

Язык Интернета слабо типизирован. Это означает, что типы данных могут быть преобразованы друг в друга произвольно, даже если мы не выполняем функцию для их приведения - это может просто случиться. На других языках, таких как Java, это дает ошибку.

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

Сознательное преобразование типов используется практически во всех языках программирования. Только неявное приведение довольно необычно - это означает, что мы можем преобразовывать типы данных без классических приведений, с операциями друг в друга. Вот пример:

Существует множество правил неявного принуждения - важно лишь понимать, что оно существует. Программистам, пришедшим с языков более низкого уровня, часто бывает трудно понять эту концепцию. Принуждение может привести к непреднамеренным ошибкам.

Вот более сложная статья об отдельных правилах принуждения.

Спасибо за чтение!

Подпишитесь на мою рассылку, чтобы оставаться в курсе