Синтаксис стрелки не является сокращением
Это часть Кодовый дневник с запятой и сыновьями — состоящий из уроков, извлеченных на работе. ты в категория JavaScript.
Последнее обновление: 2023-03-29
У меня была (Jest) имитация функциональности браузера xhr следующим образом:
const xhrMockClass = () => ({ // Эта функция (`отправить`) является важной частью этой статьи отправить: () => { this.onreadystatechange() вернуть шутку.fn() }, состояние готовности: 4, статус: 200, открыть: jest.fn(), onreadystatechange: jest.fn(), setRequestHeader: jest.fn() }) window.XMLHttpRequest = jest.fn().mockImplementation(xhrMockClass)
Вызывающий код, который я хотел протестировать, выглядел так:
export function get(url, callback = () => {}) { const xhr = новый XMLHttpRequest xhr.onreadystatechange = функция () { если (this.readyState == 4 && this.status == 200) { обратный вызов (xhr) } } постоянный асинхронный = правда xhr.open("ПОЛУЧИТЬ", URL, асинхронно) xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest') вернуть xhr.send() }
Когда я запускал код в своей тестовой среде, я получал ошибку xhr.send()
=> "Невозможно прочитать свойство onreadystatechange неопределенного"
Когда я отлаживал мока, записывая this
, оказалось undefined
const xhrMockClass = () => ({ отправить: () => { console.log(это) } })
Исправление заключалось в изменении вызова стрелки на вызов с помощью функции
ключевого слова:
const xhrMockClass = () => ({ ... отправить: функция () { this.onreadystatechange() вернуть шутку.fn() }, })
Почему это сработало? Возьмем более узкий пример оригинала (проблемный) код, чтобы объяснить, что произошло.
константный тест = () => ({ состояние: 1, фу: () => { вернуть это.состояние } })
При этом test(). foo()
вернет null
вместо 1
, которое вы могли бы
ожидать. Это связано с тем, что этот
в foo
не привязан к объекту, возвращаемому
функция test
из-за foo
— это функция стрелки!
Это так, даже если вы тестируете объекты:
window.outer = { внутренний: { состояние: 1, фу: () => { вернуть это.состояние } }, состояние: "за пределами штата" } // external.state.foo() по-прежнему дает значение undefined
Так что не используйте функции стрелок с объектными методами… обсуждение см. здесь:
https://stackoverflow.com/questions/31095710/methods-in-es6-objects-using-arrow-functions
Переписать с синтаксисом метода, чтобы заставить его работать:
константный тест = () => ({ состояние: 1, Фу () { вернуть это.состояние } })
- Т.Дж. Crowder на Stack Overflow выразился лучше всего:
«Стрелочные функции не предназначены для использования в любой ситуации просто как
укороченная версия старомодных функций.
Поэтому при определении функциональности объектов придерживайтесь синтаксиса метода или обычных функций.
- При использовании функций жирных стрелок
это
определен
). Например, в следующем кодеэто
этоundefined
, а неxhrMockClass
.
константа xhrMockClass = () => ({ отправить: () => { this.onreadystatechange() } })
Подумайте об этом:
— Когда мы вызываем xhrMockClass()
, он сразу возвращает объект
— До того, как этот объект будет возвращен, мы не сможем получить к нему доступ через это
XMLHttpRequest (XHR)
Появление XMLHttpRequest (XHR) в браузерах в середине 2000-х стало огромным успехом для веб-платформы.
- Введение
- Пример запроса XHR
- Дополнительные параметры open()
-
onreadystatechange
- Прерывание запроса XHR
- Сравнение с jQuery
- Сравнение с Fetch
- Междоменные запросы
- Загрузка файлов с помощью XHR
Введение
Появление XMLHttpRequest (XHR) в браузерах в середине 2000-х годов стало огромной победой для веб-платформы. Посмотрим, как это работает.
Вещи, которые сейчас кажутся обычными, когда-то выглядели так, как будто пришли из будущего. Я говорю, например, о GMail или Google Maps, которые в значительной степени основаны на XHR.
XHR был изобретен в Microsoft в девяностых и стал стандартом де-факто, так как все браузеры внедрили его в период 2002-2006 годов. W3C стандартизировал XMLHttpRequest в 2006 году.
Как это иногда случается с веб-платформой, изначально было несколько несоответствий, из-за которых работа с XHR в разных браузерах была совершенно другой.
Библиотеки, такие как jQuery, приобрели популярность, предоставив разработчикам простую в использовании абстракцию, что, в свою очередь, способствовало распространению этой технологии.
Пример запроса XHR
Следующий код создает объект запроса XMLHttpRequest (XHR) и прикрепляет функцию обратного вызова, которая отвечает на событие onreadystatechange
.
Соединение xhr настроено для выполнения запроса GET к https://yoursite.com
и запускается методом
:
const xhr = new XMLHttpRequest() xhr.onreadystatechange = () => { если (xhr.readyState === 4) { xhr.status === 200 ? console.log(xhr.responseText): console.error('ошибка') } } xhr.open('ПОЛУЧИТЬ', 'https://yoursite.com') xhr.send()
Дополнительные параметры open()
В приведенном выше примере мы просто передали метод и URL-адрес в запрос.
Мы также можем указать другие методы HTTP — ( получить
, отправить
, заголовки
, поставить
, удалить
, варианты
).
Другие параметры позволяют указать флаг, чтобы сделать запрос синхронным, если установлено значение false, и набор учетных данных для HTTP-аутентификации:
open(метод, URL, асинхронный, имя пользователя, пароль)
onreadystatechange
onreadystatechange
вызывается несколько раз во время запроса XHR. Мы явно игнорируем все состояния, кроме readyState === 4
, что означает, что запрос выполнен.
Состояния
- 1 (ОТКРЫТ): запрос начинается
- 2 (HEADERS_RECEIVED): заголовки HTTP получены
- 3 (ЗАГРУЗКА): начинается загрузка ответа
- 4 (ГОТОВО): ответ загружен
Прерывание запроса XHR
Запрос XHR можно прервать, вызвав метод abort()
для объекта xhr
.
Сравнение с jQuery
С помощью jQuery эти строки можно преобразовать в:
$.get('https://yoursite.com', data => { console.log(данные) }).