Синтаксис стрелки не является сокращением

Это часть Кодовый дневник с запятой и сыновьями — состоящий из уроков, извлеченных на работе. ты в категория 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,
  Фу () {
    вернуть это.состояние
  }
})
 
  1. Т.Дж. Crowder на Stack Overflow выразился лучше всего: «Стрелочные функции не предназначены для использования в любой ситуации просто как укороченная версия старомодных функций.
    Они не предназначены для замены синтаксис функции с использованием ключевого слова function. Наиболее распространенный вариант использования стрелки функции представляют собой короткие «лямбды», которые не переопределяют это, часто используются, когда передача функции в качестве обратного вызова некоторой функции.»

Поэтому при определении функциональности объектов придерживайтесь синтаксиса метода или обычных функций.

  1. При использовании функций жирных стрелок это
    независимо от лексического окружения 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 и запускается методом

send() :

 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(данные)
}).