Неожиданное окончание ввода json что это
Перейти к содержимому

Неожиданное окончание ввода json что это

  • автор:

Обработка ошибок, «try..catch»

Неважно, насколько мы хороши в программировании, иногда наши скрипты содержат ошибки. Они могут возникать из-за наших промахов, неожиданного ввода пользователя, неправильного ответа сервера и по тысяче других причин.

Обычно скрипт в случае ошибки «падает» (сразу же останавливается), с выводом ошибки в консоль.

Но есть синтаксическая конструкция try..catch , которая позволяет «ловить» ошибки и вместо падения делать что-то более осмысленное.

Синтаксис «try…catch»

Конструкция try..catch состоит из двух основных блоков: try , и затем catch :

try < // код. >catch (err) < // обработка ошибки >

Работает она так:

  1. Сначала выполняется код внутри блока try .
  2. Если в нём нет ошибок, то блок catch(err) игнорируется: выполнение доходит до конца try и потом далее, полностью пропуская catch .
  3. Если же в нём возникает ошибка, то выполнение try прерывается, и поток управления переходит в начало catch(err) . Переменная err (можно использовать любое имя) содержит объект ошибки с подробной информацией о произошедшем.

Таким образом, при ошибке в блоке try скрипт не «падает», и мы получаем возможность обработать ошибку внутри catch .

Давайте рассмотрим примеры.

    Пример без ошибок: выведет alert (1) и (2) :

try < alert('Начало блока try'); // (1) catch(err) < alert('Catch игнорируется, так как нет ошибок'); // (3) >
try < alert('Начало блока try'); // (1) catch(err) < alert(`Возникла ошибка!`); // (3)

try..catch работает только для ошибок, возникающих во время выполнения кода

Чтобы try..catch работал, код должен быть выполнимым. Другими словами, это должен быть корректный JavaScript-код.

Он не сработает, если код синтаксически неверен, например, содержит несовпадающее количество фигурных скобок:

try < catch(e)

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

Таким образом, try..catch может обрабатывать только ошибки, которые возникают в корректном коде. Такие ошибки называют «ошибками во время выполнения», а иногда «исключениями».

try..catch работает синхронно

Исключение, которое произойдёт в коде, запланированном «на будущее», например в setTimeout , try..catch не поймает:

try < setTimeout(function() < noSuchVariable; // скрипт упадёт тут >, 1000); > catch (e)

Это потому, что функция выполняется позже, когда движок уже покинул конструкцию try..catch .

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

setTimeout(function() < try < noSuchVariable; // try..catch обрабатывает ошибку! >catch < alert( "ошибка поймана!" ); >>, 1000);

Объект ошибки

Когда возникает ошибка, JavaScript генерирует объект, содержащий её детали. Затем этот объект передаётся как аргумент в блок catch :

try < // . >catch(err) < // 

Для всех встроенных ошибок этот объект имеет два основных свойства:

name Имя ошибки. Например, для неопределённой переменной это "ReferenceError" . message Текстовое сообщение о деталях ошибки.

В большинстве окружений доступны и другие, нестандартные свойства. Одно из самых широко используемых и поддерживаемых – это:

stack Текущий стек вызова: строка, содержащая информацию о последовательности вложенных вызовов, которые привели к ошибке. Используется в целях отладки.

try < lalala; // ошибка, переменная не определена! >catch(err) < alert(err.name); // ReferenceError alert(err.message); // lalala is not defined alert(err.stack); // ReferenceError: lalala is not defined at (. стек вызовов) // Можем также просто вывести ошибку целиком // Ошибка приводится к строке вида "name: message" alert(err); // ReferenceError: lalala is not defined >

Блок «catch» без переменной

Новая возможность
Эта возможность была добавлена в язык недавно. В старых браузерах может понадобиться полифил.

Если нам не нужны детали ошибки, в catch можно её пропустить:

try < // . >catch < // 

Использование «try…catch»

Давайте рассмотрим реальные случаи использования try..catch .

Как мы уже знаем, JavaScript поддерживает метод JSON.parse(str) для чтения JSON.

Обычно он используется для декодирования данных, полученных по сети, от сервера или из другого источника.

Мы получаем их и вызываем JSON.parse вот так:

let json = ''; // данные с сервера let user = JSON.parse(json); // преобразовали текстовое представление в JS-объект // теперь user - объект со свойствами из строки alert( user.name ); // John alert( user.age ); // 30

Вы можете найти более детальную информацию о JSON в главе Формат JSON, метод toJSON.

Если json некорректен, JSON.parse генерирует ошибку, то есть скрипт «падает».

Устроит ли нас такое поведение? Конечно нет!

Получается, что если вдруг что-то не так с данными, то посетитель никогда (если, конечно, не откроет консоль) об этом не узнает. А люди очень не любят, когда что-то «просто падает» без всякого сообщения об ошибке.

Давайте используем try..catch для обработки ошибки:

let json = "< некорректный JSON >"; try < let user = JSON.parse(json); // catch (e) < // . выполнение прыгает сюда alert( "Извините, в данных ошибка, мы попробуем получить их ещё раз." ); alert( e.name ); alert( e.message ); >

Здесь мы используем блок catch только для вывода сообщения, но мы также можем сделать гораздо больше: отправить новый сетевой запрос, предложить посетителю альтернативный способ, отослать информацию об ошибке на сервер для логирования, … Всё лучше, чем просто «падение».

Генерация собственных ошибок

Что если json синтаксически корректен, но не содержит необходимого свойства name ?

let json = '< "age": 30 >'; // данные неполны try < let user = JSON.parse(json); // catch (e)

Здесь JSON.parse выполнится без ошибок, но на самом деле отсутствие свойства name для нас ошибка.

Для того, чтобы унифицировать обработку ошибок, мы воспользуемся оператором throw .

Оператор «throw»

Оператор throw генерирует ошибку.

throw

Технически в качестве объекта ошибки можно передать что угодно. Это может быть даже примитив, число или строка, но всё же лучше, чтобы это был объект, желательно со свойствами name и message (для совместимости со встроенными ошибками).

В JavaScript есть множество встроенных конструкторов для стандартных ошибок: Error , SyntaxError , ReferenceError , TypeError и другие. Можно использовать и их для создания объектов ошибки.

let error = new Error(message); // или let error = new SyntaxError(message); let error = new ReferenceError(message); // . 

Для встроенных ошибок (не для любых объектов, только для ошибок), свойство name – это в точности имя конструктора. А свойство message берётся из аргумента.

let error = new Error("Ого, ошибка! o_O"); alert(error.name); // Error alert(error.message); // Ого, ошибка! o_O

Давайте посмотрим, какую ошибку генерирует JSON.parse :

try < JSON.parse("< некорректный json o_O >"); > catch(e) < alert(e.name); // SyntaxError alert(e.message); // Unexpected token b in JSON at position 2 >

Как мы видим, это SyntaxError .

В нашем случае отсутствие свойства name – это ошибка, ведь пользователи должны иметь имена.

let json = '< "age": 30 >'; // данные неполны try < let user = JSON.parse(json); // alert( user.name ); > catch(e) < alert( "JSON Error: " + e.message ); // JSON Error: Данные неполны: нет имени >

В строке (*) оператор throw генерирует ошибку SyntaxError с сообщением message . Точно такого же вида, как генерирует сам JavaScript. Выполнение блока try немедленно останавливается, и поток управления прыгает в catch .

Теперь блок catch становится единственным местом для обработки всех ошибок: и для JSON.parse и для других случаев.

Проброс исключения

В примере выше мы использовали try..catch для обработки некорректных данных. А что, если в блоке try <. >возникнет другая неожиданная ошибка? Например, программная (неопределённая переменная) или какая-то ещё, а не ошибка, связанная с некорректными данными.

let json = '< "age": 30 >'; // данные неполны try < user = JSON.parse(json); // catch(err) < alert("JSON Error: " + err); // JSON Error: ReferenceError: user is not defined // (не JSON ошибка на самом деле) >

Конечно, возможно все! Программисты совершают ошибки. Даже в утилитах с открытым исходным кодом, используемых миллионами людей на протяжении десятилетий – вдруг может быть обнаружена ошибка, которая приводит к ужасным взломам.

В нашем случае try..catch предназначен для выявления ошибок, связанных с некорректными данными. Но по своей природе catch получает все свои ошибки из try . Здесь он получает неожиданную ошибку, но всё также показывает то же самое сообщение "JSON Error" . Это неправильно и затрудняет отладку кода.

К счастью, мы можем выяснить, какую ошибку мы получили, например, по её свойству name :

try < user = < /*. */ >; > catch(e) < alert(e.name); // "ReferenceError" из-за неопределённой переменной >

Есть простое правило:

Блок catch должен обрабатывать только те ошибки, которые ему известны, и «пробрасывать» все остальные.

Техника «проброс исключения» выглядит так:

  1. Блок catch получает все ошибки.
  2. В блоке catch(err) мы анализируем объект ошибки err .
  3. Если мы не знаем как её обработать, тогда делаем throw err .

В коде ниже мы используем проброс исключения, catch обрабатывает только SyntaxError :

let json = '< "age": 30 >'; // данные неполны try < let user = JSON.parse(json); if (!user.name) < throw new SyntaxError("Данные неполны: нет имени"); >blabla(); // неожиданная ошибка alert( user.name ); > catch(e) < if (e.name == "SyntaxError") < alert( "JSON Error: " + e.message ); >else < throw e; // проброс (*) >>

Ошибка в строке (*) из блока catch «выпадает наружу» и может быть поймана другой внешней конструкцией try..catch (если есть), или «убьёт» скрипт.

Таким образом, блок catch фактически обрабатывает только те ошибки, с которыми он знает, как справляться, и пропускает остальные.

Пример ниже демонстрирует, как такие ошибки могут быть пойманы с помощью ещё одного уровня try..catch :

function readData() < let json = '< "age": 30 >'; try < // . blabla(); // ошибка! >catch (e) < // . if (e.name != 'SyntaxError') < throw e; // проброс исключения (не знаю как это обработать) >> > try < readData(); >catch (e) < alert( "Внешний catch поймал: " + e ); // поймал! >

Здесь readData знает только, как обработать SyntaxError , тогда как внешний блок try..catch знает, как обработать всё.

try…catch…finally

Подождите, это ещё не всё.

Конструкция try..catch может содержать ещё одну секцию: finally .

Если секция есть, то она выполняется в любом случае:

  • после try , если не было ошибок,
  • после catch , если ошибки были.

Расширенный синтаксис выглядит следующим образом:

try < . пробуем выполнить код. >catch(e) < . обрабатываем ошибки . >finally

Попробуйте запустить такой код:

try < alert( 'try' ); if (confirm('Сгенерировать ошибку?')) BAD_CODE(); >catch (e) < alert( 'catch' ); >finally

У кода есть два пути выполнения:

  1. Если вы ответите на вопрос «Сгенерировать ошибку?» утвердительно, то try -> catch -> finally .
  2. Если ответите отрицательно, то try -> finally .

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

Например, мы хотим измерить время, которое занимает функция чисел Фибоначчи fib(n) . Естественно, мы можем начать измерения до того, как функция начнёт выполняться и закончить после. Но что делать, если при вызове функции возникла ошибка? В частности, реализация fib(n) в коде ниже возвращает ошибку для отрицательных и для нецелых чисел.

Секция finally отлично подходит для завершения измерений несмотря ни на что.

Здесь finally гарантирует, что время будет измерено корректно в обеих ситуациях – и в случае успешного завершения fib и в случае ошибки:

let num = +prompt("Введите положительное целое число?", 35) let diff, result; function fib(n) < if (n < 0 || Math.trunc(n) != n) < throw new Error("Должно быть целое неотрицательное число"); >return n let start = Date.now(); try < result = fib(num); >catch (e) < result = 0; >finally < diff = Date.now() - start; >alert(result || "возникла ошибка"); alert( `Выполнение заняло $ms` );

Вы можете это проверить, запустив этот код и введя 35 в prompt – код завершится нормально, finally выполнится после try . А затем введите -1 – незамедлительно произойдёт ошибка, выполнение займёт 0ms . Оба измерения выполняются корректно.

Другими словами, неважно как завершилась функция: через return или throw . Секция finally срабатывает в обоих случаях.

Переменные внутри try..catch..finally локальны

Обратите внимание, что переменные result и diff в коде выше объявлены до try..catch .

Если переменную объявить в блоке, например, в try , то она не будет доступна после него.

finally и return

Блок finally срабатывает при любом выходе из try..catch , в том числе и return .

В примере ниже из try происходит return , но finally получает управление до того, как контроль возвращается во внешний код.

function func() < try < return 1; >catch (e) < /* . */ >finally < alert( 'finally' ); >> alert( func() ); // сначала срабатывает alert из finally, а затем этот код

try..finally

Конструкция try..finally без секции catch также полезна. Мы применяем её, когда не хотим здесь обрабатывать ошибки (пусть выпадут), но хотим быть уверены, что начатые процессы завершились.

function func() < // начать делать что-то, что требует завершения (например, измерения) try < // . >finally < // завершить это, даже если все упадёт >>

В приведённом выше коде ошибка всегда выпадает наружу, потому что тут нет блока catch . Но finally отрабатывает до того, как поток управления выйдет из функции.

Глобальный catch

Зависит от окружения

Информация из данной секции не является частью языка JavaScript.

Давайте представим, что произошла фатальная ошибка (программная или что-то ещё ужасное) снаружи try..catch , и скрипт упал.

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

Такого способа нет в спецификации, но обычно окружения предоставляют его, потому что это весьма полезно. Например, в Node.js для этого есть process.on("uncaughtException") . А в браузере мы можем присвоить функцию специальному свойству window.onerror, которая будет вызвана в случае необработанной ошибки.

window.onerror = function(message, url, line, col, error) < // . >;

message Сообщение об ошибке. url URL скрипта, в котором произошла ошибка. line , col Номера строки и столбца, в которых произошла ошибка. error Объект ошибки.

  

Роль глобального обработчика window.onerror обычно заключается не в восстановлении выполнения скрипта – это скорее всего невозможно в случае программной ошибки, а в отправке сообщения об ошибке разработчикам.

Существуют также веб-сервисы, которые предоставляют логирование ошибок для таких случаев, такие как https://errorception.com или http://www.muscula.com.

Они работают так:

  1. Мы регистрируемся в сервисе и получаем небольшой JS-скрипт (или URL скрипта) от них для вставки на страницы.
  2. Этот JS-скрипт ставит свою функцию window.onerror .
  3. Когда возникает ошибка, она выполняется и отправляет сетевой запрос с информацией о ней в сервис.
  4. Мы можем войти в веб-интерфейс сервиса и увидеть ошибки.

Итого

Конструкция try..catch позволяет обрабатывать ошибки во время исполнения кода. Она позволяет запустить код и перехватить ошибки, которые могут в нём возникнуть.

try < // исполняем код >catch(err) < // если случилась ошибка, прыгаем сюда // err - это объект ошибки >finally < // выполняется всегда после try/catch >

Секций catch или finally может не быть, то есть более короткие конструкции try..catch и try..finally также корректны.

Объекты ошибок содержат следующие свойства:

  • message – понятное человеку сообщение.
  • name – строка с именем ошибки (имя конструктора ошибки).
  • stack (нестандартное, но хорошо поддерживается) – стек на момент ошибки.

Если объект ошибки не нужен, мы можем пропустить его, используя catch < вместо catch(err) < .

Мы можем также генерировать собственные ошибки, используя оператор throw . Аргументом throw может быть что угодно, но обычно это объект ошибки, наследуемый от встроенного класса Error . Подробнее о расширении ошибок см. в следующей главе.

Проброс исключения – это очень важный приём обработки ошибок: блок catch обычно ожидает и знает, как обработать определённый тип ошибок, поэтому он должен пробрасывать дальше ошибки, о которых он не знает.

Даже если у нас нет try..catch , большинство сред позволяют настроить «глобальный» обработчик ошибок, чтобы ловить ошибки, которые «выпадают наружу». В браузере это window.onerror .

Что пошло не так? Устранение ошибок JavaScript

Когда вы создали игру «Угадай номер» в предыдущей статье, вы, возможно, обнаружили, что она не работает. Не бойтесь — эта статья призвана избавить вас от разрыва волос над такими проблемами, предоставив вам несколько простых советов о том, как найти и исправить ошибки в программах JavaScript.

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

Типы ошибок

Когда вы делаете что-то не так в коде, есть два основных типа ошибок, с которыми вы столкнётесь:

  • Синтаксические ошибки: Это орфографические ошибки в коде, которые фактически заставляют программу вообще не запускаться, или перестать работать на полпути — вам также будут предоставлены некоторые сообщения об ошибках. Обычно они подходят для исправления, если вы знакомы с правильными инструментами и знаете, что означают сообщения об ошибках!
  • Логические ошибки: Это ошибки, когда синтаксис действительно правильный, но код не тот, каким вы его предполагали, что означает, что программа работает успешно, но даёт неверные результаты. Их часто сложнее находить, чем синтаксические ошибки, так как обычно не возникает сообщение об ошибке, которое направляет вас к источнику ошибки.

Ладно, все не так просто — есть и другие отличия, которые вы поймёте, пока будете изучать язык JavaScript глубже. Однако вышеуказанной классификации достаточно на раннем этапе вашей карьеры. Мы рассмотрим оба эти типа в дальнейшем.

Ошибочный пример

Чтобы начать работу, давайте вернёмся к нашей игре с угадыванием чисел — за исключением того, что мы будем изучать версию с некоторыми преднамеренными ошибками. Перейдите в Github и сделайте себе локальную копию number-game-errors.html (см. здесь как это работает).

  1. Чтобы начать работу, откройте локальную копию внутри вашего любимого текстового редактора и вашего браузера.
  2. Попробуйте сыграть в игру — вы заметите, что когда вы нажимаете кнопку «Submit guess», она не работает!

Примечание: Возможно, у вас может быть собственная версия игрового примера, которая не работает, которую вы можете исправить! Мы по-прежнему хотели бы, чтобы вы работали над статьёй с нашей версией, чтобы вы могли изучать методы, которые мы здесь преподаём. Затем вы можете вернуться и попытаться исправить ваш пример.

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

Исправление синтаксических ошибок

Раньше в курсе мы заставили вас набрать некоторые простые команды JavaScript в консоль разработчика JavaScript (если вы не можете вспомнить, как открыть это в своём браузере, следуйте предыдущей ссылке, чтобы узнать, как это сделать). Что ещё более полезно, так это то, что консоль предоставляет вам сообщения об ошибках всякий раз, когда существует синтаксическая ошибка внутри JavaScript, которая подаётся в механизм JavaScript браузера. Теперь пойдём на охоту.

  1. Перейдите на вкладку, в которой у вас есть number-game-errors.html, и откройте консоль JavaScript. Вы должны увидеть сообщение об ошибке в следующих строках:
  2. Это довольно простая ошибка для отслеживания, и браузер даёт вам несколько полезных бит информации, которые помогут вам (скриншот выше от Firefox, но другие браузеры предоставляют аналогичную информацию). Слева направо, у нас есть:
    • Красный «x» означает, что это ошибка.
    • Сообщение об ошибке, указывающее, что пошло не так: «TypeError: guessSubmit.addeventListener не является функцией»
    • Ссылка «Узнать больше», которая ссылается на страницу MDN, которая объясняет, что эта ошибка означает в огромных количествах деталей.
    • Имя файла JavaScript, который ссылается на вкладку «Отладчик» консоли разработчика. Если вы перейдёте по этой ссылке, вы увидите точную строку, где подсвечивается ошибка.
    • Номер строки, в которой находится ошибка, и номер символа в этой строке, где первая ошибка. В этом случае у нас есть строка 86, символ номер 3.
  3. Если мы посмотрим на строку 86 в нашем редакторе кода, мы найдём эту строку:

.addeventListener("click", checkGuess); 

**Примечание:**См. наш TypeError: «x» не является справочной страницей функций для получения дополнительной информации об этой ошибке.

Синтаксические ошибки: второй раунд

Примечание: console.log() это часто используемая функция отладки, которая выводит значение в консоль. Поэтому она будет выводить значение lowOrHi в консоли, как только мы попытаемся установить его в строке 48.

  1. Сохраните и обновите страницу, и вы увидите, что ошибка исчезла.
  2. Теперь, если вы попробуете ввести значение и нажать кнопку "Submit guess", вы увидите . другую ошибку!
  3. На этот раз сообщается об ошибке: "TypeError: lowOrHi is null", в строке 78.

Примечание: Null — это специальное значение, которое означает "ничего" или "не значение". Поэтому lowOrHi был объявлен и инициализирован без значения — у него нет типа или значения.

Примечание: Эта ошибка не появилась, как только страница была загружена, потому что эта ошибка произошла внутри функции (внутри checkGuess() < . >блока). Об этом вы узнаете более подробно в нашей более поздней статье о функциях, код внутри функций выполняется в отдельной области для кода внешних функций. В этом случае код не был запущен, и ошибка не была брошена до тех пор, пока функция checkGuess() не была запущена строкой 86.

.textContent = "Last guess was too high!"; 
const lowOrHi = document.querySelector("lowOrHi"); 
.log(lowOrHi); 

  • Сохраните и обновите, и вы должны увидеть результат работы console.log() в консоли браузера. Разумеется, значение lowOrHi на данный момент равно null , поэтому определённо существует проблема в строке 48.
  • Давайте подумаем о том, что может быть проблемой. Строка 48 использует метод document.querySelector() для получения ссылки на элемент, выбирая его с помощью селектора CSS. Посмотрев далее наш файл, мы можем найти обсуждаемый элемент

    :

    p class="lowOrHi">/p> 

    Примечание: Загляните на справочную страницу TypeError: "x" is (not) "y", чтобы узнать больше об этой ошибке.

    Синтаксические ошибки: третий раунд

    1. Теперь, если вы снова попробуете сыграть в игру, вы должны добиться большего успеха — игра должна играть абсолютно нормально, пока вы не закончите игру, либо угадав нужное число, либо потеряв жизни.
    2. На данном этапе игра снова слетает, и выводится такая же ошибка, как и в начале — "TypeError: resetButton.addeventListener is not a function"! Однако, теперь она происходит из-за строки 94.
    3. Посмотрев на строку 94, легко видеть, что здесь сделана такая же ошибка. Нам просто нужно изменить addeventListener на addEventListener .

    Логическая ошибка

    На этом этапе игра должна проходить отлично, однако, поиграв несколько раз, вы, несомненно заметите, что случайное число, которое вы должны угадать, всегда 0 или 1. Определённо не совсем так, как мы хотим, чтобы игра была разыграна!

    Безусловно, где-то в игре есть логическая ошибка — игра не возвращает ошибку, она просто работает неправильно.

      Найдём переменную randomNumber , и строку где в первый раз устанавливали случайное число. Пример, в котором мы храним случайное число, которое должны угадать, на строке 44:

    let randomNumber = Math.floor(Math.random()) + 1; 

    И на строке 113, где мы генерируем случайное число, каждый раз после окончания игры:

    = Math.floor(Math.random()) + 1; 
    .log(randomNumber); 

    Работаем через логику

    Чтобы исправить это, давайте рассмотрим как работает строка. Первое, мы вызываем Math.random() , который генерирует случайное десятичное число, между 0 и 1, например 0.5675493843.

    .random(); 

    Дальше, мы передаём результат вызова Math.random() через Math.floor() , который округляет число вниз, до ближайшего целого числа. Затем мы добавляем 1 к данному результату:

    Math.floor(Math.random()) + 1;

    Округление случайного десятичного числа к меньшему, всегда будет возвращать 0, так что добавление к нему единицы будет возвращать всегда 1. Нам нужно умножить случайное число на 100, прежде чем мы округлим его к меньшему. Следующая строка вернёт нам случайное число между 0 и 99:

    .floor(Math.random() * 100); 

    поэтому нам нужно добавить 1, чтоб нам возвращалось случайное число между 1 и 100:

    .floor(Math.random() * 100) + 1; 

    А теперь, исправьте обе строки с ошибками, затем сохраните и обновите, игра должна работать так, как мы и планировали!

    Другие распространённые ошибки

    Существуют и другие распространённые ошибки, которые вы обнаружите в своём коде. В этом разделе показано большинство из них.

    SyntaxError: отсутствует ; перед постановкой

    Эта ошибка обычно означает что вы упустили точку с запятой в конце одной из ваших строк кода, но иногда ошибка может быть более загадочной. Например, если мы изменим эту строку внутри функции checkGuess() :

    var userGuess = Number(guessField.value); 
    var userGuess === Number(guessField.value); 

    Это вызовет данную ошибку, потому что браузер подумает, что вы пытались сделать что-то другое. Вы должны быть уверены, что вы не перепутали оператор присваивания ( = ), который присваивает значение переменной — с оператором сравнения ( === ), который строго сравнивает операнды, и возвращает true / false .

    Примечание: Загляните на справочную страницу Синтаксическая ошибка: пропущен символ ; до объявления инструкции для получения дополнительной информации об этой ошибке.

    В программе всегда говорится, что вы выиграли, независимо от того, что вы ввели

    Причиной этому является все то же перепутывание оператора присваивания ( = ) со строгим сравнением ( === ). Например, если мы изменим внутри checkGuess() эту строку кода:

    if (userGuess === randomNumber)  
    if (userGuess = randomNumber)  

    мы всегда будем получать true , заставляя программу сообщать, что игра была выиграна. Будьте осторожны!

    SyntaxError: отсутствует ) после списка аргументов

    Эта ошибка проста — обычно она означает, что вы пропустили закрывающую скобку с конца вызова функции / метода.

    Примечание: Загляните на справочную страницу SyntaxError: missing ) after argument list для получения дополнительной информации об этой ошибке.

    SyntaxError: missing : after property id

    Эта ошибка обычно связана с неправильно сформированным объектом JavaScript, но в этом случае нам удалось получить её, изменив

    function checkGuess()  
    function checkGuess(  

    Это заставило браузер думать, что мы пытаемся передать содержимое функции в функцию в качестве аргумента. Будьте осторожны с этими скобками!

    SyntaxError: missing > after function body

    Это легко — обычно это означает, что вы пропустили одну из ваших фигурных скобок из функции или условной структуры. Мы получили эту ошибку, удалив одну из закрывающих фигурных скобок возле нижней части функции checkGuess() .

    SyntaxError: expected expression, got 'string' or SyntaxError: unterminated string literal

    Эти ошибки обычно означает, что вы пропустили открывающую или закрывающую кавычку для строковых значений. В первой ошибки выше, строка будет заменена на неожиданный персонаж (ей) , что браузер нашёл вместо кавычек в начале строки. Вторая ошибка означает , что строка не закончилась кавычки.

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

    Примечание: : Смотрите наш SyntaxError: Неожиданный токен и SyntaxError: незавершённая строка эталонных страниц для получения более подробной информации об этих ошибках.

    Резюме

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

    Смотрите также

    • Есть много других типов ошибок, которые не перечислены здесь; мы составляем ссылку , которая объясняет , что они означают подробно - см. ссылку ошибки JavaScript .
    • Если вы столкнётесь с любыми ошибками в коде, которые вы не знаете , как исправить после прочтения этой статьи, вы можете получить помощь! Спросите на нить обучения Область дискурсе , или в #mdn IRC канал на Mozilla IRC. Расскажите нам, какая у вас ошибка, и мы постараемся вам помочь. Приложите пример своего кода для большей ясности проблемы.
    • Назад
    • Обзор: Первые шаги
    • Далее

    Found a content problem with this page?

    • Edit the page on GitHub.
    • Report the content issue.
    • View the source on GitHub.

    This page was last modified on 3 авг. 2023 г. by MDN contributors.

    Your blueprint for a better internet.

    15 полезных плагинов для Figma, которые существенно ускорят работу

    Рассказываем про плагины для Figma, автоматизирующие рабочую рутину.

    Степан Степанов

    Степан Степанов

    Автор статей по дизайну. В веб-дизайн пришёл в 2013 году, осознанно начал заниматься с 2015 года. Параллельно освоил вёрстку. Время от времени публикую переводы на Habr.

    Особенности плагинов в Figma

    Команда Figma очень бережно относится к своему детищу и прислушивается к мнению сообщества. Благодаря этому в середине июля 2019 года была выпущена бета-версия редактора с поддержкой плагинов. А уже в начале августа презентовали обновлённую Figma со встроенными плагинами. Любой разработчик или дизайнер, знающий базовый HTML и JavaScript, мог подать заявку и принять участие в их разработке.

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

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

    Где находятся плагины

    Откройте программу, авторизуйтесь под своим Google-аккаунтом, перейдите на главную страницу редактора Figma. Слева на панели увидите пункт Plugins (он находится сразу под Drafts).

    Нажав на Plugins, вы окажетесь на странице плагинов. Они сгруппированы — рекомендуемые, популярные и установленные.

    Также можно посмотреть все плагины, которые есть на данный момент, если нажать на кнопку Browse all plugins.

    Установка плагинов

    Философия FIgma — в простоте, поэтому установка плагинов простая и понятная для любого пользователя.

    Установить плагины можно двумя способами:

    • На странице всех плагинов напротив нужного нажмите на кнопку Install — он будет автоматически установлен, состояние кнопки изменится на Installed, а плагин будет помещен в список группы Installed.
    • На отдельной странице плагина выберите нужный, перейдите на него и нажмите на кнопку Install для установки.

    Установка плагина происходит мгновенно. Еще одно нажатие на кнопку инсталляции приводит к его деактивации.

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

    Обзор 15 плагинов для дизайнера

    Я отобрал пятнадцать простых и функциональных плагинов, которые будут полезны большинству дизайнеров:

    • Unsplash — для быстрого автозаполнения блоков фотографиями.
    • Map Maker — добавляет карты.
    • Charts — для визуализации данных.
    • Iconify — для иконок.
    • Autoflow — визуализирует связи между объектами.
    • Content Reel — для наполнения макета сайта контентом.
    • Blobs — делает симпатичные кляксы.
    • Image tracer — умеет переводить растр в вектор.
    • Figmotion — для анимации.
    • Find and Replace — ищет и заменяет текст.
    • Nisa Text Splitter — для работы с таблицами и списками.
    • Spellchecker — проверяет грамматику.
    • Isometric — для быстрого создания изометрии.
    • Datavizer — умеет создавать графики и гистограммы.
    • Icon Resizer — для быстрого изменения размеров иконок.

    Unsplash

    Плагин для быстрого автозаполнения блоков фотографиями

    Один из самых популярных и востребованных плагинов в Figma: он в разы сокращает время работы с контентом. Особенно полезен, когда нужно быстро заполнить сайт и нет времени даже на то, чтобы переключаться с вкладки на вкладку, искать и сохранять изображения.

    Давайте посмотрим на его работу. Выберите плагин — нажмите правой кнопкой мыши в любом месте холста. Выберите пункт Plugins — Unsplash.

    Появится окно плагина.

    Выделите все карточки на холсте и выберите любую тематику (у нас в примере портреты).

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

    Map Maker

    Плагин для добавления карт

    Map Maker позволяет быстро создавать уникальную настраиваемую карту для вашего проекта. В настоящее время он поддерживает Google Maps и Mapbox. Разберем процесс создания карты на основе Google Maps.

    Выберите плагин Map Maker.

    По умолчанию установлена вкладка Google Maps, она нам и нужна.

    Перейдите на поле Address и введите нужную локацию, например, Paris.

    Ниже адресной строки вы можете поменять тип карты и зум на тот, который вас устроит.

    Теперь самое интересное — стиль карты. Поменять стиль карты можно, если перейти по одной из двух ссылок в блоке Custom Style.

    Давайте перейдем по первой ссылке Snazzy Map и посмотрим, что это.

    Перейдя по ссылке на ресурс, мы видим информационное окно, предупреждающее, что сервис не может в полной мере поддерживать Google Maps. С июля 2019 года компания Google взимает плату за использование их API. Суммы достаточно большие. Чтобы не закрыть сервис и хоть как-то оставаться на плаву, руководство Snazzy Map было вынуждено урезать самые дорогие функции и тем самым сократить свои расходы, оставив сервис бесплатным.

    Вы можете посмотреть и изучить возможности сервиса самостоятельно, он очень простой. Судьба Snazzy Map непонятна, поскольку аналог появился у Google и смысл в использовании именно его отпадает.

    Посмотрим, что предлагается в Custom Style по ссылке Google Official Map Style.

    Нажмите Create a Style. Теперь вы можете подобрать нужный стиль карты.

    Если не знаете, какой стиль выбрать, обратите внимание на Silver. Он одинаково хорошо смотрится на любом проекте за счет своей ненавязчивости.

    Также можно немного почистить карту: убрать лишние мешающие названия, достопримечательности и дороги. Для этого есть специальный фильтр Adjust density of features (Регулировка плотности функций).

    Также можно поменять цвета и сделать более точные настройки карты. Для этого нажмите внизу кнопку More Options.

    Когда карта готова, нажмите Finish, появится следующее окно:

    Нажмите на ссылку Copy JSON — код скопируется в буфер обмена, это нужно для того, чтобы получить код настроенной карты и перенести его в наш плагин.

    Возвращаемся обратно в Figma и вставляем скопированный код в поле Custom Style.

    Обратите внимание на то, как изменилась карта в окне просмотра. Это значит, что все настройки применились, карта отображается корректно.

    Далее осталось только нажать на кнопку Make Map, чтобы применить настроенную карту к нашему блоку.

    Я немного уменьшил зум, и вот что из этого получилось.

    Charts

    Плагин для визуализации данных

    Если вы часто проектируете дашборды, то плагин Charts сильно облегчит выполнение рутины и позволит вам создавать симпатичные графики.

    Как он работает?

    Выбираем Charts из выпадающего списка плагинов.

    Получаем вот такое окно:

    Charts довольно простой и интуитивно понятный. Давайте немного пройдемся по настройкам.

    • Choose chart type — выбираем тип диаграммы.
    • Configure — настраиваем конфигурацию, количество линий, точек, начало и конец диапазона данных.
    • Preview — окно просмотра.

    Можно создавать любое количество разных диаграмм, а потом настраивать их под свои задачи.

    Iconify

    Плагин для иконок

    Очень полезный и нужный плагин, который должен быть в арсенале любого дизайнера. Суть его проста — быстрый поиск и добавление нужной иконки в SVG-формате в ваш проект.

    Выбираем из списка плагин Iconify.

    Получаем окно со всевозможными сборниками иконок. Коллекций иконок огромное количество.

    Очень удобно реализована подача коллекций иконок, понятно их количество, виден размер, а также указаны компания и автор.

    Пользоваться иконками очень просто: можно подобрать из конкретной коллекции или найти иконку через поиск.

    Затем выбранную иконку можно немного преобразовать — повернуть на определенный угол или отзеркалить по вертикали или горизонтали, а также задать нужный цвет.

    Autoflow

    Плагин, визуализирующий связи между объектами

    Один из самых простых и самых популярных на сегодняшний день плагинов.

    Плагин позволяет показывать связь между объектами — очень полезная штука для изображения пользовательских сценариев и любых ситуаций, где важно передать принадлежность и последовательность событий.

    Чтобы создать взаимосвязь, достаточно выделить два объекта и выбрать в выпадающем списке Autoflow.

    Чтобы каждый раз не выбирать из списка, воспользуйтесь сочетанием клавиш Ctrl+Alt+P. Оно позволяет активировать последний плагин, которым вы пользовались.

    Вот так в три клика можно получить связи между нужными объектами.

    Content Reel

    Плагин для наполнения макета сайта контентом

    Плагин нужен, чтобы наполнить страницы макета уникальным контентом. Он выдаёт имена, телефоны, адреса, сайты, email, а также аватары и иконки.

    Я создал восемь карточек с таким наполнением:

    Задача — получить на всех карточках разный контент. Начинаем с выбора плагина.

    Получаем вот такое окно.

    Далее выберите поочередно все имена, адреса, email и нажмите нужный пункт в окне плагина, как показано на гифке.

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

    Если ранее я говорил, что плагин сыроват, то теперь скажу, что это мегаплагин, огромный респект разработчикам.

    Blobs

    Плагин, делающий симпатичные кляксы

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

    Выбираем Blobs из списка.

    Появляется вот такое окно.

    И, по сути, это и есть весь плагин, всего две настройки — сложность и контраст, количество и там, и там ограничено десятью. Давайте посмотрим, что может этот малыш.

    Еще минута — и готово вот такое чудо:

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

    Image tracer

    Плагин, который умеет переводить растр в вектор

    Этот плагин нужен в том случае, когда у вас есть растровое изображение, но вам нужен вектор, а обводить нет ни времени, ни желания.

    Преимущества изображений с четкими очертаниями и однородной заливкой в векторе перед растром:

    • Вектор можно редактировать.
    • Можно масштабировать без потери качества.
    • Можно быстро менять цвет.
    • Можно задавать обводку.

    Итак, ищем растровое изображение, желательно с четкими очертаниями и контрастной заливкой. Выбираем плагин.

    Окно активируется только в том случае, если вы уже перенесли изображение в редактор и выделили его.

    Работает он следующим образом.

    Существуют дополнительные опции по более точной настройке плагина. Настроить их можно, если нажать на кнопку Show Options.

    Пожалуй, самая важная опция — это blur. Она предназначена для сглаживания пикселей и превращения рваной линии в более плавную.

    Теперь вам не придется пользоваться дополнительным софтом (Illustrator или Corel) специально для того, чтобы трассировать изображение.

    Figmotion

    Плагин для анимации

    Figmotion позволяет создавать анимацию прямо в Figma. Существенный плюс этого плагина — нет необходимости переключаться на другие пакеты анимации, как, например, Principle или After Effects. Если вы не умеете с ними работать, но анимация вам жизненно необходима, то плагин Figmotion должен быть в вашем арсенале.

    Когда установите плагин, самое время его запустить. Перейдите в Figma, создайте новый файл проекта, выберите для работы Frame и нарисуйте фигуру, например треугольник. Теперь нажмите на фрейм правой кнопкой мыши для вызова контекстного меню. Выберите Plugins — Figmotion — Open Figmotion.

    Откроется вот такое окно.

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

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

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

    Чтобы передвинуть треугольник, нужно выбрать свойство x — это означает, что мы будем двигать элемент по оси x. Напротив каждого свойства нарисован ромб. Он нужен, чтобы ставить ключи анимации на панели Timeline.

    Переместите оранжевый маркер на нулевую секунду (0ms) и нажмите на ромб (ключ анимации напротив свойства), который отмечен на скриншоте выше. Появится ключ анимации на нулевом кадре, откуда и начнёт движение треугольник.

    Следующим шагом нужно обозначить окончание движения элемента — для этого переместите оранжевый маркер на 0,7 секунды (что соответствует 700ms). Сделать это можно двумя способами:

    • Промотайте горизонтальный ползунок, который находится ниже временной шкалы, и установите оранжевый маркер на нужное значение. Конечно, есть вероятность, что будет некоторая погрешность и не удастся установить четкое значение 700ms. Такая чёткость нужна не всегда, но так на порядок удобнее.
    • Довольно точный способ — произвольно установите второй ключевой кадр на любом временном значении и один раз нажмите на установленном ключевом кадре. Появится окно, в котором можно ввести интересующее вас значение, — туда и переместится ключевой кадр.

    Удалить ключевой кадр можно с помощью кнопки Remove в появившемся окне, как это показано выше. Также в этом окне настраивается смягчение движения элемента как в начале, так и в конце. Используется тот же принцип, что и в After Effects — Easy Ease.

    Продолжим создание анимации: установите ключевой кадр на 700ms любым способом и выберите easeOut. Таким образом элемент завершит анимацию более плавно.

    Теперь нужно обозначить вектор движения и окончательное местоположение элемента. Делается это довольно легко: передвиньте треугольник вправо на нужное расстояние, на панели свойств элемента посмотрите значение оси x. Это значение введите в окно ключевого кадра.

    Правда, есть небольшой нюанс, который я обнаружил опытным путём. От фактического значения оси x (когда установите его в окне ключевого кадра) будет вычтен размер, равный половине вашего элемента, и фактически ось x будет равна 514. А не 608, как в моём примере.

    Поэтому, если вы хотите получить элемент точно по конкретной координате от края объекта, учитывайте, что придётся прибавить число, равное половине этого объекта. Поэтому я прибавил 94 и получил ровно 608. Но в окне ключевого кадра будет 702.

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

    Для такого случая есть выход — поменять привязку центра ключевого кадра объекта. Меняется в выпадающем окне, где и все значения ключевого кадра.

    Вроде как это отличный выход, но опять же есть «но»: данное свойство применяется для всех ключевых кадров всех свойств, что становится очередной проблемой. Ниже я рассмотрю подобный случай, а пока завершим нашу анимацию.

    Давайте посмотрим промежуточный вариант. Чтобы проиграть анимацию, перейдите к нулевой секунде и нажмите пробел или кнопку Play в верхней части окна.

    Анимация треугольника по оси x.

    Работа с JSON

    Обозначение объектов JavaScript (JSON - JavaScript Object Notation) - стандартный текстовый формат для представления структурированных данных на основе синтаксиса объекта JavaScript. Он обычно используется для передачи данных в веб-приложениях (например, отправка некоторых данных с сервера клиенту,таким образом чтобы это могло отображаться на веб-странице или наоборот). Вы будете сталкиваться с этим довольно часто, поэтому в этой статье мы даём вам все, что вам нужно для работы с JSON используя JavaScript, включая парсинг JSON, чтобы вы могли получить доступ к данным внутри него при создании JSON.

    Необходимые знания: Базовая компьютерная грамотность, базовые знания HTML и CSS, знакомство с основами JavaScript (см. First steps и Building blocks) и основами OOJS (see Introduction to objects (en-US) ).
    Цель: Понять, как работать с данными, хранящимися в JSON, и создавать свои собственные объекты JSON.

    Нет, действительно, что такое JSON?

    JSON - текстовый формат данных, следующий за синтаксисом объекта JavaScript, который был популяризирован Дугласом Крокфордом. Несмотря на то, что он очень похож на буквенный синтаксис объекта JavaScript, его можно использовать независимо от JavaScript, и многие среды программирования имеют возможность читать (анализировать) и генерировать JSON.

    JSON существует как строка,что необходимо при передаче данных по сети. Он должен быть преобразован в собственный объект JavaScript, если вы хотите получить доступ к данным. Это не большая проблема. JavaScript предоставляет глобальный объект JSON, который имеет методы для преобразования между ними.

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

    Объект JSON может быть сохранён в собственном файле, который в основном представляет собой текстовый файл с расширением .json и MIME type application/json .

    Структура JSON

    Как описано выше, JSON представляет собой строку, формат которой очень похож на буквенный формат объекта JavaScript. Вы можете включать одни и те же базовые типы данных внутри JSON, так же как и в стандартном объекте JavaScript - строки, числа, массивы, булевы и другие объектные литералы. Это позволяет построить иерархию данных, к примеру, так:

     "squadName": "Super hero squad", "homeTown": "Metro City", "formed": 2016, "secretBase": "Super tower", "active": true, "members": [  "name": "Molecule Man", "age": 29, "secretIdentity": "Dan Jukes", "powers": ["Radiation resistance", "Turning tiny", "Radiation blast"] >,  "name": "Madame Uppercut", "age": 39, "secretIdentity": "Jane Wilson", "powers": [ "Million tonne punch", "Damage resistance", "Superhuman reflexes" ] >,  "name": "Eternal Flame", "age": 1000000, "secretIdentity": "Unknown", "powers": [ "Immortality", "Heat Immunity", "Inferno", "Teleportation", "Interdimensional travel" ] > ] > 

    Если бы мы загрузили этот объект в программу JavaScript, создали переменную с названием superHeroes , мы могли бы затем получить доступ к данным внутри неё, используя те же самые точечную и скобочную нотации, которые мы рассмотрели в статье JavaScript object basics. Например:

    .homeTown; superHeroes["active"]; 

    Чтобы получить доступ к последующим данным по иерархии, вам просто нужно объединить требуемые имена свойств и индексы массивов. Например, чтобы получить доступ к третьей сверхспособности второго героя, указанного в списке участников, вы должны сделать следующее:

    ["members"][1]["powers"][2]; 
    1. Сначала у нас есть имя переменной - superHeroes .
    2. Внутри мы хотим получить доступ к свойству members , поэтому мы используем ['members'] .
    3. members содержат массив, заполненный объектами. Мы хотим получить доступ ко второму объекту внутри массива, поэтому мы используем [1] .
    4. Внутри этого объекта мы хотим получить доступ к свойству powers , поэтому мы используем ['powers'] .
    5. Внутри свойства powers находится массив, содержащий сверхспособности выбранного героя. Нам нужен третий, поэтому мы используем [2] .

    Примечание: . Мы сделали JSON, видимый выше, доступным внутри переменной в нашем примере JSONTest.html (см. исходный код). Попробуйте загрузить это, а затем получить доступ к данным внутри переменной через консоль JavaScript вашего браузера.

    Массивы как JSON

    Выше мы упоминали ,что JSON текст выглядит практически так же как и JavaScript объект,и это почти правильно.Причина,по которой мы говорим почти правильно заключается в том ,что массив также валиден JSON например:

    [  "name": "Molecule Man", "age": 29, "secretIdentity": "Dan Jukes", "powers": ["Radiation resistance", "Turning tiny", "Radiation blast"] >,  "name": "Madame Uppercut", "age": 39, "secretIdentity": "Jane Wilson", "powers": [ "Million tonne punch", "Damage resistance", "Superhuman reflexes" ] > ] 

    Вышесказанное вполне справедливо для JSON. Вам просто нужно получить доступ к элементам массива (в его анализируемой версии), начиная с индекса массива, например [0]["powers"][0] .

    Другие примечания

    • JSON - это чисто формат данных - он содержит только свойства, без методов.
    • JSON требует двойных кавычек, которые будут использоваться вокруг строк и имён свойств. Одиночные кавычки недействительны.
    • Даже одна неуместная запятая или двоеточие могут привести к сбою JSON-файла и не работать. Вы должны быть осторожны, чтобы проверить любые данные, которые вы пытаетесь использовать (хотя сгенерированный компьютером JSON с меньшей вероятностью включает ошибки, если программа генератора работает правильно). Вы можете проверить JSON с помощью приложения вроде JSONLint.
    • JSON может принимать форму любого типа данных, допустимого для включения в JSON, а не только массивов или объектов. Так, например, одна строка или номер будут действительным объектом JSON.
    • В отличие от кода JavaScript, в котором свойства объекта могут не заключаться в двойные кавычки, в JSON в качестве свойств могут использоваться только строки заключённые в двойные кавычки.

    Активное обучение: Работа с примером JSON

    Итак, давайте рассмотрим пример, чтобы показать то, как мы можем использовать некоторые данные JSON на веб-сайте.

    Начало работы

    Для начала создайте локальные копии наших файлов heroes.html и style.css. Последний содержит простой CSS для стилизации нашей страницы, в то время как первый содержит очень простой HTML-код сущности:

    header>header> section>section> 
    var header = document.querySelector("header"); var section = document.querySelector("section"); 

    Мы собираемся загрузить его на нашу страницу и использовать некоторые изящные манипуляции DOM, чтобы отобразить их, например:

    Получение JSON

    Чтобы получить JSON, мы будем использовать API, называемый XMLHttpRequest (часто называемый XHR). Это очень полезный объект JavaScript, который позволяет нам делать сетевые запросы для извлечения ресурсов с сервера через JavaScript (например, изображения, текст, JSON, даже фрагменты HTML), что означает, что мы можем обновлять небольшие разделы контента без необходимости перезагрузки всей страницы. Это привело к более отзывчивым веб-страницам и звучит захватывающе, но, к сожалению, выходит за рамки этой статьи, чтобы изучить это гораздо более подробно.

      Начнём с того, что мы собираемся сохранить URL-адрес JSON, который мы хотим получить в переменной. Добавьте нижеследующий код JavaScript:

    var requestURL = "https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json"; 
    var request = new XMLHttpRequest(); 
    .open("GET", requestURL); 
    • Метод HTTP, который следует использовать при выполнении сетевого запроса. В этом случае GET самый подходящий, так как мы просто извлекаем некоторые простые данные.
    • URL-адрес для запроса - это URL-адрес файла JSON, который мы сохранили ранее.
    .responseType = "json"; request.send(); 
    .onload = function ()  var superHeroes = request.response; populateHeader(superHeroes); showHeroes(superHeroes); >; 

    Здесь мы сохраняем ответ на наш запрос (доступный в свойстве response ) в переменной superHeroes ; эта переменная теперь будет содержать объект JavaScript, основанный на JSON! Затем мы передаём этот объект двум вызовам функций - первый из них заполнит правильными данными, а второй создаст информационную карту для каждого героя в команде и вставляет её в .

    Мы свернули код в обработчик событий, который запускается, когда событие загрузки запускается в объекте запроса (см. onload (en-US) ) - это связано с тем, что событие загрузки запускается, когда ответ успешно возвращается; поступая таким образом,это гарантия того, что request.response определённо будет доступен, когда мы начнём работу с ним.

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

    function populateHeader(jsonObj)  var header = document.querySelector("header"); var myH1 = document.createElement("h1"); myH1.textContent = jsonObj["squadName"]; header.appendChild(myH1); var myPara = document.createElement("p"); myPara.textContent = "Hometown: " + jsonObj["homeTown"] + " // Formed: " + jsonObj["formed"]; header.appendChild(myPara); > 

    Мы назвали параметр jsonObj , чтобы напомнить себе, что этот объект JavaScript возник из JSON. Здесь мы сначала создаём элемент (en-US) с createElement() , устанавливаем его textContent равным свойству squadName объекта, а затем добавляем его в заголовок с помощью appendChild() . Затем мы выполняем очень похожую операцию с абзацем: создаём его, устанавливаем его текстовое содержимое и добавляем его в заголовок. Единственное различие заключается в том, что его текст задан, как конкатенированная строка, содержащая как homeTown , так и formed свойства объекта.

    Создание информационных карт героя

    Затем добавьте следующую функцию внизу кода, которая создаёт и отображает карты супергероев:

    function showHeroes(jsonObj)  var section = document.querySelector("section"); var heroes = jsonObj["members"]; for (var i = 0; i  heroes.length; i++)  var myArticle = document.createElement("article"); var myH2 = document.createElement("h2"); var myPara1 = document.createElement("p"); var myPara2 = document.createElement("p"); var myPara3 = document.createElement("p"); var myList = document.createElement("ul"); myH2.textContent = heroes[i].name; myPara1.textContent = "Secret identity: " + heroes[i].secretIdentity; myPara2.textContent = "Age: " + heroes[i].age; myPara3.textContent = "Superpowers:"; var superPowers = heroes[i].powers; for (var j = 0; j  superPowers.length; j++)  var listItem = document.createElement("li"); listItem.textContent = superPowers[j]; myList.appendChild(listItem); > myArticle.appendChild(myH2); myArticle.appendChild(myPara1); myArticle.appendChild(myPara2); myArticle.appendChild(myPara3); myArticle.appendChild(myList); section.appendChild(myArticle); > > 

    Для начала сохраним свойство members объекта JavaScript в новой переменной. Этот массив содержит несколько объектов, которые содержат информацию для каждого героя.

    Затем мы используем for loop для циклического прохождения каждого объекта в массиве. Для каждого из них мы:

    1. Создаём несколько новых элементов: , , три

      и
      .

    2. Устанавливаем , чтобы содержать name текущего героя.
    3. Заполняем три абзаца своей secretIdentity , age и строкой, в которой говорится: «Суперспособности:», чтобы ввести информацию в список.
    4. Сохраняем свойство powers в другой новой переменной под названием superPowers - где содержится массив, в котором перечислены сверхспособности текущего героя.
    5. Используем другой цикл for , чтобы прокрутить сверхспособности текущего героя , для каждого из них мы создаём элемент
    6. , помещаем в него сверхспособности, а затем помещаем listItem внутри элемента
      ( myList ) с помощью appendChild() .
    7. Последнее, что мы делаем, это добавляем ,

      и
      внутри ( myArticle ), а затем добавляем в . Важное значение имеет порядок, в котором добавляются элементы, так как это порядок, который они будут отображать внутри HTML.

    Примечание: . Если вам не удаётся заставить этот пример работать, попробуйте обратиться к нашему исходному коду heroes-finished.html (см. также он работает в режиме live).

    Примечание: . Если у вас возникли проблемы после нотации точек / скобок, которые мы используем для доступа к объекту JavaScript, в этом поможет открытие файла superheroes.json на другой вкладке или в текстовом редакторе ,и обращаться к нему каждый раз, когда вам нужен JavaScript. Вы также можете обратиться к нашей статье JavaScript objectbasics чтобы получить дополнительную информацию о нотации точек и скобок.

    Преобразование между объектами и текстом

    Вышеприведённый пример был прост с точки зрения доступа к объекту JavaScript, потому что мы задали XHR-запрос для прямого преобразования ответа JSON в объект JavaScript, используя:

    .responseType = "json"; 

    Но иногда нам не так везёт - иногда мы получаем сырую строку JSON и нам нужно преобразовать её в объект самостоятельно. И когда мы хотим отправить объект JavaScript по сети, нам нужно преобразовать его в JSON (строку) перед отправкой. К счастью, эти две проблемы настолько распространены в веб-разработке, что встроенный объект JSON доступен в браузерах, которые содержат следующие два метода:

    • parse() : принимает строку JSON в качестве параметра и возвращает соответствующий объект JavaScript.
    • stringify() : принимает объект, как параметр и возвращает эквивалентную строковую JSON строку.

    Вы можете увидеть первый метод в действии в нашем примере heroes-finished-json-parse.html (см. исходный код) - это то же самое, что и в примере, который мы создали ранее, за исключением того, что мы установили XHR для возврата сырого JSON текста, затем используется parse() , чтобы преобразовать его в фактический объект JavaScript. Ключевой фрагмент кода находится здесь:

    .open("GET", requestURL); request.responseType = "text"; // now we're getting a string! request.send(); request.onload = function ()  var superHeroesText = request.response; // get the string from the response var superHeroes = JSON.parse(superHeroesText); // convert it to an object populateHeader(superHeroes); showHeroes(superHeroes); >; 

    Как вы могли догадаться, stringify() работает обратным образом. Попробуйте ввести следующие строки в консоль JavaScript браузера один за другим, чтобы увидеть его в действии:

    var myJSON =  name: "Chris", age: "38" >; myJSON; var myString = JSON.stringify(myJSON); myString; 

    Здесь мы создаём объект JavaScript, затем проверяем, что он содержит, а затем преобразуем его в строку JSON, используя stringify() , сохраняя возвращаемое значение в новой переменной, а затем снова проверяем его.

    Резюме

    В этой статье мы предоставили вам простое руководство по использованию JSON в ваших программах, в том числе о том, как создавать и анализировать JSON, и как получить доступ к данным, заблокированным внутри него. В следующей статье мы рассмотрим объектно-ориентированный JavaScript.

    Смотрите также

    • JSON object reference page
    • XMLHttpRequest object reference page
    • Using XMLHttpRequest
    • HTTP request methods
    • Official JSON web site with link to ECMA standard
    • Назад
    • Обзор: Objects
    • Далее

    В этом модуле

    • Основы объекта
    • Объектно-ориентированный JavaScript для начинающих
    • Прототипы объектов
    • Наследование в JavaScript
    • Работа с данными JSON
    • Практика построения объектов
    • Добавление функций в нашу демонстрацию прыгающих шаров

    Found a content problem with this page?

    • Edit the page on GitHub.
    • Report the content issue.
    • View the source on GitHub.

    This page was last modified on 3 авг. 2023 г. by MDN contributors.

    Your blueprint for a better internet.

  • Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *