Синтаксис стрелки не является сокращением
Это часть Кодовый дневник с запятой и сыновьями — состоящий из уроков, извлеченных на работе. ты в категория 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 выразился лучше всего:
«Стрелочные функции не предназначены для использования в любой ситуации просто как
укороченная версия старомодных функций.

Они не предназначены для замены синтаксис функции с использованием ключевого слова function. Наиболее распространенный вариант использования стрелки функции представляют собой короткие «лямбды», которые не переопределяют это, часто используются, когда передача функции в качестве обратного вызова некоторой функции.»
Поэтому при определении функциональности объектов придерживайтесь синтаксиса метода или обычных функций.
- При использовании функций жирных стрелок
это независимо от лексического окружения is (т.е. контекст it wasопределен). Например, в следующем кодеэтоэто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(данные)
}).



