Перевод статьи «7 tips to handle undefined in JavaScript»
undefined в JavaScript — настоящий кошмар начинающего фронтендера. В чём отличие undefined и NULL, если даже сравнение NULL == undefined выводит true, и как обрабатывать ошибку undefined? Давайте разбираться.
Примечание Вы читаете улучшенную версию некогда выпущенной нами статьи.
- Что такое undefined в JavaScript
- Как избежать undefined в JavaScript
- Значение undefined в массивах
- Отличие NULL и undefined в JavaScript
- Заключение
Проявления ошибки «javascript»
По причине возникновения ошибки у пользователя будут появляться проблемы при открытии видеороликов и запуске музыкальных композиций. Кроме того, некоторые участники соцсети отмечают, что у них не открываются сообщения и присутствуют задержки при загрузке страниц.
Справка. Перед тем как предпринимать конкретные действия по устранению неполадки, следует перезагрузить компьютер. В некоторых случаях это помогает избавиться от ошибки.
Помимо невозможности запуска мультимедийных файлов, сама система ВК оповестит человека о возникших неполадках: в левом верхнем углу страниц появится надпись на красном фоне «javascript error adslight is not defined». Также в предупреждении могут находиться слова «a function», «CustomMedia» и прочие. Все они свидетельствует об одном типе ошибки. Разберемся с возможными методами ее устранения.
Значение undefined в массивах
Вы получаете undefined при попытке доступа к элементу массива с индексом вне пределов массива.
const colors = [‘blue’, ‘white’, ‘red’]; colors[5]; // => undefined colors[-1]; // => undefined
Массив colors имеет 3 элемента, поэтому корректные индексы равны 0, 1 и 2. Поскольку в индексах массива 5 и -1 нет элементов, значения colors[5] и colors[-1] получают значение undefined.
В JavaScript вы можете столкнуться с так называемыми разрежёнными массивами. Эти массивы имеют пробелы, то есть на некоторых индексах не определены никакие элементы. Когда делаем попытку получить доступ к пустому значению в разрежённом массиве, на выходе получаем undefined:
const sparse1 = new Array(3); sparse1; // => [, , ] sparse1[0]; // => undefined sparse1[1]; // => undefined const sparse2 = [‘white’, ,’blue’] sparse2; // => [‘white’, , ‘blue’] sparse2[1]; // => undefined
sparse1 создается путем вызова конструктора Array с числовым первым аргументом. Он имеет 3 пустых элемента. sparse2 создается с литералом массива, второй элемент которого отсутствует. В любом из этих массивов доступ к пустому элементу оценивается как undefined.
Очистка файла hosts
В системной папке Windows находится файл hosts, который отвечает за маршрутизацию вводимых в браузере адресов. Его могут использовать мошенники для подмены оригинального сайта ВК, но находящиеся там сторонние записи также оказывают влияние на работу Java-элементов. Решение в данном случае заключается в очистке документа и приведении его в первоначальный вид.
Пошаговая инструкция:
- Открыть проводник компьютера и перейти в папку, которая расположена по такому пути: C:\Windows\System32\drivers\etc. Буква диска может отличаться, если система установлена на другой раздел, но в любом случае нужно отыскать папку Windows и дальше отталкиваться от нее.
- Открыть файл hosts с помощью блокнота.
- Убрать лишние записи находящиеся после строки «# ::1 localhost».
- Сохранить документ и перезагрузить компьютер.
Рекомендуем: Как добавить аудиозапись в вк
Проблема должна исчезнуть, если это не так, необходимо попробовать другие варианты ее устранения.
Как избежать undefined в JavaScript
Неинициализированная переменная
Объявленная переменная, которая еще не имеет значения (не инициализирована), по умолчанию undefined. Пример:
let myVariable; myVariable; // => undefined
Переменная myVariable уже объявлена, но ещё не имеет присвоенного значения. Попытка обратиться к ней закончится выводом undefined. Чтобы это исправить, достаточно присвоить переменной значение. Чем меньше переменная существует в неинициализированном состоянии, тем лучше.
Ниже приведены способы решения проблемы.
const и let вместо var
Объявленные таким образом объекты и переменные находятся в области видимости, ограниченной текущим блоком кода, и находятся во временной мёртвой зоне до момента присвоения им значения.
При использовании неизменяемых данных (констант) рекомендуется инициализировать их как const:
const myVariable = ‘initial’
Константа не подвергается неинициализированному состоянию, и получить значение undefined в этом случае невозможно.
Product Owner
Exness, Лимассол, Кипр, По итогам собеседования
tproger.ru
Вакансии на tproger.ru
Если вам нужно менять значение переменной, то обозначьте её как let и также присваивайте ей начальное значение:
let index = 0
Проблема var заключается в поднятии переменных: где бы ни находилось объявление, это равнозначно тому, что переменную объявили в начале кода.
function bigFunction() { // код… myVariable; // => undefined // код… var myVariable = ‘Initial value’; // код… myVariable; // => ‘Initial value’ } bigFunction();
В этом случае переменная myVariable содержит undefined до получения значения:
myVariable = ‘Initial value’
Если же переменную объявить как let, она останется недоступной до момента присвоения ей значения. Таким образом, использование const или let снизит риск получения значения undefined в JavaScript.
Усиление связности
Связность характеризует степень взаимосвязи элементов модуля (пространства имён, класса, метода, блока кода). Сильная связность предпочтительнее, поскольку предполагает, что элементы модуля должны фокусироваться исключительно на одной задаче. Это поможет модулю быть:
- сфокусированным и понятным;
- легко поддерживаемым и поддающимся рефакторингу;
- многоразовым;
- простым для тестирования.
Блок кода сам по себе может считаться небольшим модулем. Чтобы извлечь выгоду из преимуществ сильной связности, нужно держать переменные как можно ближе к блоку кода, который их использует.
Вот классический пример того, как не надо делать:
function someFunc(array) { var index, item, length = array.length; // некоторый код… // некоторый код… for (index = 0; index < length; index++) { item = array[index]; // некоторый код… } return ‘some result’; }
index, item и length объявляются в начале функции, но используются они лишь ближе к концу. Всё время между объявлением переменной в начале и до использования её в цикле index и item не инициализируются и выводят undefined. Разумнее переместить переменные ближе к месту их применения:
function someFunc(array) { // некоторый код… // некоторый код… const length = array.length; for (let index = 0; index < length; index++) { const item = array[index]; // некоторый код } return ‘some result’; }
Доступ к несуществующему свойству
Попытка получить доступ к несуществующему свойству объекта JavaScript заканчивается undefined. Пример:
let favoriteMovie = { title: ‘Blade Runner’ }; favoriteMovie.actors; // => undefined
favoriteMovie — объект с одним значением title. Доступ к несуществующему свойству actors приведёт к выводу undefined.
Сам по себе доступ к не вызовет ошибку, а вот при попытке получить значение из несуществующего свойства выведется ошибка:
TypeError: Cannot read property of undefined
Проблема в особенностях JavaScript: свойство может быть установлено или отсутствовать. Хорошее решение — установка правил, которые обязывают задать свойствам значения.
Но не всегда возможно контролировать объекты, с которыми приходится работать. Такие объекты могут иметь разный набор свойств в различных сценариях, и каждый из них нужно обрабатывать вручную.
Реализуем функцию append(array, toAppend), которая добавляет в начале и/или в конце массива новые элементы:
function append(array, toAppend) { const arrayCopy = array.slice(); if (toAppend.first) { arrayCopy.unshift(toAppend.first); } if (toAppend.last) { arrayCopy.push(toAppend.last); } return arrayCopy; } append([2, 3, 4], { first: 1, last: 5 }); // => [1, 2, 3, 4, 5] append([‘Hello’], { last: ‘World’ }); // => [‘Hello’, ‘World’] append([8, 16], { first: 4 }); // => [4, 8, 16]
Поскольку объект toAppend может удалять первые или последние свойства, необходимо проверить их существование с помощью условий if(toAppend.first){} и if(toAppend.last){}.
Вот только undefined, как false, NULL, 0, NaN и ‘ ‘, является ложными значением, а в текущей реализации функция append() не позволяет вставлять ложные элементы:
append([10], { first: 0, last: false }); // => [10]
0 и false — ложные значения, потому что if (toAppend.first){} и if (toAppend.last){} фактически сравниваются с ложными значениями, и эти элементы не вставляются в массив. Функция возвращает исходный массив [10] без изменений.
Наличие свойства
К счастью, JavaScript предлагает множество способов определить, имеет ли объект определённое свойство:
- obj.prop !== undefined в JavaScript позволяет проверить undefined, сравнив с ним объект;
- typeof obj.prop !== ‘undefined’ проверяет тип значения свойства;
- obj.hasOwnProperty(‘prop’) проверяет объект на наличие собственного свойства;
- ‘prop’ in obj проверяет объект на наличие собственного или унаследованного свойства.
Рекомендацией в этом случае будет использование оператора in , чтобы проверить, имеет ли объект определённое свойство, не обращаясь к фактическому значению этого свойства:
function append(array, toAppend) { const arrayCopy = array.slice(); if (‘first’ in toAppend) { arrayCopy.unshift(toAppend.first); } if (‘last’ in toAppend) { arrayCopy.push(toAppend.last); } return arrayCopy; } append([2, 3, 4], { first: 1, last: 5 }); // => [1, 2, 3, 4, 5] append([10], { first: 0, last: false }); // => [0, 10, false]
‘first’ in toAppend ( как и ‘last’ in toAppend) выводит true, независимо от существующего свойства. В других случаях выводится — false.
Использование оператора in устраняет проблему со вставкой ложных элементов 0 и false. Теперь добавление элементов в начале и в конце массива [10] приводит к ожидаемому результату: [0, 10, false].
Деструктуризация доступа к свойствам объекта
Деструктуризация объекта позволяет устанавливать значение по умолчанию, если свойство не существует: удобно для исключения прямого контакта с undefined:
const object = { }; const { prop = ‘default’ } = object; prop; // => ‘default’
Применяя преимущества деструктуризации объекта, реализуем quote():
function quote(str, config) { const { char = ‘»‘, skipIfQuoted = true } = config; const length = str.length; if (skipIfQuoted && str[0] === char && str === char) { return str; } return char + str + char; } quote(‘Hello World’, { char: ‘*’ }); // => ‘*Hello World*’ quote(‘»Welcome»‘, { skipIfQuoted: true }); // => ‘»Welcome»‘
const { char = ‘»‘, skipIfQuoted = true } = config в одной строкe извлекает свойства char и skipIfQuoted из объекта config.
Если некоторые свойства недоступны в объекте config, деструктуризация задаёт значения по умолчанию: ‘»‘ для char и false для skipIfQuoted. К счастью, функцию можно улучшить.
Переместим деструктуризацию в раздел параметров и установим значение по умолчанию (пустой объект { }) для параметра config, чтобы пропустить второй аргумент, когда будет достаточно значений по умолчанию:
function quote(str, { char = ‘»‘, skipIfQuoted = true } = {}) { const length = str.length; if (skipIfQuoted && str[0] === char && str === char) { return str; } return char + str + char; } quote(‘Hello World’, { char: ‘*’ }); // => ‘*Hello World*’ quote(‘Sunny day’); // => ‘»Sunny day»‘
Деструктурирующее присваивание гарантирует, что используется пустой объект, если второй аргумент не указан вообще. В результате вы избегаете возникновения значения undefined в JavaScript.
Свойство по умолчанию
Есть простой способ установить значения по умолчанию для свойств объекта, и имя ему Spread syntax:
const unsafeOptions = { fontSize: 18 }; const defaults = { fontSize: 16, color: ‘black’ }; const options = { …defaults, …unsafeOptions }; options.fontSize; // => 18 options.color; // => ‘black’
Инициализатор объекта распространяет свойства из исходных объектов defaults и unsafeOptions. Важен порядок, в котором указаны исходные объекты: свойства более позднего исходного объекта перезаписывают более ранние. Независимо от ситуации, объект всегда содержит полный набор свойств, и появление undefined невозможно.
Параметры функции
Функция, имеющая определённые параметры, должна вызываться с одинаковым количеством аргументов. В таком случае параметры получают ожидаемые значения:
function multiply(a, b) { a; // => 5 b; // => 3 return a * b; } multiply(5, 3); // => 15
При вызове функции multiply(5, 3) параметры a и b получают соответствующие значения 5 и 3. Умножение рассчитывается как ожидаемое: 5 * 3 = 15.
Но что происходит, когда пропускается аргумент при вызове? Параметр внутри функции получает значение undefined. Как этого избежать?
Лучшим подходом является использование параметров по умолчанию из ES2015:
function multiply(a, b = 2) { a; // => 5 b; // => 2 return a * b; } multiply(5); // => 10 multiply(5, undefined); // => 10
Значение b = 2 в сигнатуре функции гарантирует, что если b получит значение undefined, то по умолчанию параметр изменится на 2.
Возвращаемое значение функции
В JavaScript функция, которая не имеет оператора return, возвращает значение undefined:
function square(x) { const res = x * x; } square(2); // => undefined
То же происходит, если return присутствует, но без какого-либо выражения рядом:
function square(x) { const res = x * x; return; } square(2); // => undefined
Указывая значение для return, можно получить желаемый результат:
function square(x) { const res = x * x; return res; } square(2); // => 4
Теперь вызов функции выведет нужное значение.
Оператор void
Оператор void выполняет выражение и возвращает undefined вне зависимости от результата:
void 1; // => undefined void (false); // => undefined void {name: ‘John Smith’}; // => undefined void Math.min(1, 3); // => undefined
Одним из вариантов использования оператора void является переопределение результата выполнения выражения и возврат undefined в случае возникновения неожиданных результатов выполнения функции.
Переустановка компонентов Java
Деятельность вируса или устаревание ПО, могли оказать влияние на нормальную работу Java. Следует скачать и переустановить программу. Для этого требуется посетить сайт https://www.java.com/ru/download/. На открывшейся странице нужно нажать «Загрузить бесплатно», затем выбрать папку для сохранения. После скачивания файл необходимо запустить и следовать дальнейшим инструкциям установщика.
Чтобы полностью исключить негативное влияние устаревшего ПО рекомендуется также переустановить Flash Player. Ссылка для загрузки установщика: https://get.adobe.com/ru/flashplayer/. Важно снять галочки на первой странице, чтобы исключить установку дополнительных программ.
Отличие NULL и undefined в JavaScript
Основное отличие в том, что undefined представляет значение переменной, которая ещё не была инициализирована, а NULL — намеренное отсутствие объекта.
Допустим, переменная number определена, но ей не назначено начальное значение:
let number; number; // => undefined
То же самое произойдёт при попытке доступа к несуществующему свойству объекта:
const obj = { firstName: ‘Dmitri’ }; obj.lastName; // => undefined
Или переменная должна ожидать возвращение объекта функции, но по какой-то причине создание объекта невозможно. В этом случае NULL является значимым индикатором недостающего объекта. Например, clone() — это функция, которая клонирует простой объект JavaScript. Ожидается, что функция вернёт объект:
function clone(obj) { if (typeof obj === ‘object’ && obj !== NULL) { return Object.assign({}, obj); } return NULL; } clone({name: ‘John’}); // => {name: ‘John’} clone(15); // => NULL clone(NULL); // => NULL
Но clone() может быть вызван с пустым аргументом: 15 или NULL. В этом случае функция не может создать клон, поэтому возвращает NULL — индикатор отсутствующего объекта.
В JavaScript существуют проверки на NULL и undefined. Оператор typeof демонстрирует различие между двумя значениями:
typeof undefined; // => ‘undefined’ typeof NULL; // => ‘object’
Строгий оператор равенства === также отличает undefined от NULL:
let nothing = undefined; let missingObject = NULL; nothing === missingObject; // => false
Вам также может быть интересна наша статья про обработку ошибок в JavaScript.
Очистка кеша
В процессе работы браузера создаются временные фалы, которые снижают потребляемый трафик при загрузке интернет-страниц. Большое скопление таких документов может негативно сказываться на работе обозревателя и Java-элементов. Рассмотрим процесс очистки кеша на примере браузера Chrome:
- Нажать комбинацию клавиш Ctrl+Shift+Del.
- Во всплывающем окне отметить галочкой строки «Файлы cookie» и «Прочие файлы, сохраненные в кеше».
- В верхней части выбрать временной диапазон. Лучше указать значение «За все время».
- Внизу кликнуть по кнопке «Удалить данные».
- Перезапустить браузер и проверить работу мультимедийных элементов ВКонтакте.
Следуя указанным в статье рекомендациям, получится избавиться от ошибки «javascript error». Прежде всего, следует попросту перезагрузить ПК, и только потом приступать к более серьезным действиям.
Что такое undefined в JavaScript
undefined является специальным значением. Согласно спецификации ECMAScript, undefined в JavaScript можно получить при доступе к неинициализированным переменным, несуществующим свойствам объекта, несуществующим элементам массива, etc. Пример:
let number; number; // => undefined let movie = { name: ‘Interstellar’ }; movie.year; // => undefined let movies = [‘Interstellar’, ‘Alexander’]; movies[3]; // => undefined
Как видим, undefined выводится при попытке доступа к:
- неинициализированной переменной number;
- несуществующему свойству объекта movie.year;
- несуществующему элементу массива movies[3].
Оператор typeof возвращает строку undefined для неопределённого значения:
typeof undefined === ‘undefined’; // => true
Оператор typeof отлично подходит для проверки значения undefined в JavaScript:
let nothing; typeof nothing === ‘undefined’; // => true
Что это за ошибка Вконтакте
Данный баг может быть вызван многими причинами. Наиболее распространенные из них — устаревшие или битые расширения, непостоянное интернет-соединение. Реже подобные сбои вызывают вирусы, трояны и угонщики браузера. Также следует упомянуть про плановые работы на сайте ВК, которые в последнее время выполняются очень часто. Многие считают, что ошибка напрямую связана с установленным в Windows пакетом Java, но это абсолютно разные вещи и обновление Джавы вам не поможет.
Ошибка Вконтакте «JavaScript error: str is undefined»
Выводы
Избавились от javascript error mutations are not initialized?
Проблема с ошибкой “javascript error mutations are not initialized” встречается каждому. Но решается она совсем по-разному.
Может пройти и сама по себе, если это было связано с техническими работами на сайте. На помощь придет и пресловутая перезагрузка с полной проверкой компьютера на вирусы.
Прежде чем копаться в реестре, попробуйте еще открыть свою страницу через другой браузер, режим инкогнито или добавив букву m, чтобы получилось m.vk.com.
Мобильная версия приложения несколько упрощена, поэтому иногда ошибки в ней не возникает.
Если же и это всё не очень работает, установите все необходимые обновления, в частности, Java и Adobe Flash Player.
Браузер тоже попробуйте обновить при наличии новой версии. До этого еще можете очистить кэш как самой страницы, так и браузера в целом.
В крайнем случае же зайдите в реестр, чтобы отредактировать файл Hosts.
Если же ничего из этого не помогает, но ошибка появляется только на сайте Вконтакте, имеет смысл обратиться в техническую поддержку.