Как и любая компьютерная программа, JavaScript нуждается в наведении порядка в данных, в их структурировании. На языке JavaScript мы говорим, что если данные имеют одинаковую структуру, то они имеют одинаковый тип. Внутренняя организация данных может быть простой, как ДА или НЕТ, а может быть весьма замысловатой, как дерево HTML-элементов или маршруты на карте навигатора.

Примитивные типы. JavaScript предлагает разработчику несколько простых, примитивных, типов. Среди них: booleannumberstring. Примитивными эти типы называют за то, что значения этих типов нельзя поменять. Их можно клонировать, встроить в другие значения... Через минуту увидим как это происходит

Работа с наборами. Дополнительно JavaScript предлагает несколько типов объектов для работы с наборами — массивы, словари, множества. Это очень кстати, попробуй вспомни, как эффективно реализовать сортировку.

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

Давайте обсудим детали разных типов данных, как примитивных, так и встроенных. Поговорим и о кастомных типах.

Примитивные типы

JavaScript различает семь типов:

undefined — обозначает тип значения переменной, которую объявили, но не инициализировали. Этот тип для данных, которых нет.

boolean — принимает только два значения «истина» и «ложь».

number — попытка научиться записывать любое число в ограниченную память компьютера (провалилась).

string — последовательность символов. JavaScript умеет преобразовывать значение любого примитивного типа в строку. Значение типа string в JavaScript неизменяемое, нельзя изменить одну букву в слове.

symbol — специальный тип данных. Задача значений типа symbol — служить специальными именами для обозначения специальных свойств объектов. Так много слов «специально», что мы дадим разъяснения ниже.

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

object — кроме примитивных типов в JavaScript есть структурные типы (объекты), а среди объектов особо выделяют функции. Обратите внимание, что в JavaScript функции это тоже объекты.

А как же nullnull — ещё одна возможность обозначить данные, которых нет. Да, в JavaScript есть целых два способа для обозначения ситуации, когда в переменной нет значения. Обратите внимание, что в JavaScript null это значение, а не тип данных и это значение может содержаться в JSON, а undefined в JSON не бывает.

Тип undefined

Когда вы объявляете переменную, но не присваиваете ей значение, переменная получает значение «по умолчанию» и это значение undefined, которое имеет тип undefined.

let buffer;

Переменная buffer объявлена с ключевым словом let, но до тех пока она не получила явного значения ее значение undefined.

Хитрость JavaScript в том, что иногда разработчик присваивает переменной результат работы функции, но переменная все равно остается undefined. В следующем примере buffer получает значение при объявлении. Можете ли вы догадаться почему buffer всё равно undefined?

function trickyComputation (){
  let a = 0;
  while(a<3){
    a+=2;
  }
}
let buffer = trickyComputation();

Все дело в том, что trickyComputationне возвращает значения. Попробуйте рассуждать о том, что цель функции — «присвоить значение» ключевому слову return. В вышеприведенном примере нет return, и этот самый воображаемый return остается неинициализированным, отсюда и undefined.

Будьте внимательны к функциям.

Тип boolean

В JavaScript про любое значение можно задать вопрос «похоже ли оно на правду?». Значение true — правда, false — ложь. Пустое значение обычно значит false.

Посмотрим на практике. Для проверки правдивости будем пользоваться вот таким методом showTrueness.

const showTrueness = (n,value)=> console.log(`${n} - ${value?'true':'false'}`);

Вот явная ложь:

// эти значения похожи на ложь
showTrueness(1,false); // false
showTrueness(2,''); // false
showTrueness(3,0) // false

Когда значение отличается от банально-начального, оно обычно истинно.

showTrueness(1, true); // true
showTrueness(2, 42); // true
showTrueness(3, 'false') // true

Как видите, слово false получает приговор — истина! Но это еще не самый курьёзный случай с boolean:

showTrueness(1, []); // true
showTrueness(2, {}); // true
showTrueness(3, [] === []); // false
showTrueness(4, {} === {}); // false

Хотя обычно пустые значения это ложь, пустой массив (1) и пустой объект (2) оказались истиной. А ещё в следующем отрывке JavaScript рассматривает число 0 эквивалентной строке ‘0’.

Видите 0=='0' показывает true. При этом по отдельности число 0 и строка '0' относятся к разным типам.

showTrueness(1, 0 == '0'); // true
showTrueness(2, 0); // false
showTrueness(3, '0'); // true

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

Для избежания сюрпризов используйте явное преобразования значений между типами и строгое сравнение (===) (! ==). В этом вам поможет набор правил eslinter от академии.

Тип number

Тип значения number предназначен для моделирования действительных чисел. Действительных чисел очень много — бесконечно много — а компьютерная память ограничена. Инженерам из IEEE пришлось даже выпустить отдельный международный стандарт для чисел с плавающей точкой — IEEE 754.

Во многих случаях числа с плавающей точкой ведут себя нормально. Сумма чисел 1 и 2 равна 3, а сумма чисел 0.1 и 0.2 равна сумме чисел 0.2 и 0.1. Но это не всегда так, и 0.1 + 0.2 может быть не равно 0.3. Если в школе вам говорили, что от перемены мест сумма не меняется, то в JavaScript это не всегда верно.

И если будете делать выписку в крипто-банке, два раза подумайте, в каком порядке вы хотите складывать числа. Потому что значение переменной currentBalanceV1 больше значения переменной currentBalanceV2, а всё потому что величины складываемых чисел сильно отличаются.

showTrueness(1, 1+2 === 3); // true

const lastMonthCredits = Array.from ({length:30},()=>Number.EPSILON/10);
const previousMonthBalance = 0.8;
const currentBalanceV1 = previousMonthBalance + lastMonthCredits.reduce((a,b)=>a+b,0);
const currentBalanceV2 = 0 + lastMonthCredits.reduce((a,b)=>a+b,previousMonthBalance);
showTrueness(2, currentBalanceV1>currentBalanceV2); // true

showTrueness(3, 0.1+0.2 === 0.2+0.1) // true

Советы при работе с числами

  • При работе с числами старайтесь сначала делать действия над числами сравнимой величины
  • При работе с числами старайтесь сравнивать их порядок, (что больше, а что меньше), а не равенство.
  • Изучите назначение предопределенных констант Number.MAX_SAFE_INTEGERNumber.EPSILON и других.

Задание для самопроверки. На сколько отличаются currentBalanceV1currentBalanceV2 и previousMonthBalance?

Тип string

Строки в JavaScript — это неизменяемые цепочки букв. Вы можете добавлять строки одну к другой, брать нужную букву по порядку. Нумерация букв в строке начинается с нуля, поэтому вы видите в примере (-1).

const show = (value)=>console.log(value);
const alfavit = 'абвгдеёжзийклмнопрстуфхцчшщъыьэюя';
show(alfavit); // "абвгдеёжзийклмнопрстуфхцчшщъыьэюя"
show(alfavit[1-1]); // "а"
show(alfavit[33-1]); //"я"

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

alfavit[2-1]='*';
show(alfavit); // "абвгдеёжзийклмнопрстуфхцчшщъыьэюя"

В виде строк можно хранить любой вид данных, нужно только договориться. Однако мы не рекомендуем вам изобретать велосипед. Лучше используйте общепринятые способы преобразования данных в строку и обратно: JSON.stringifyJSON.parse (для превращения в JSON и обратно), Intl.NumberFormatIntl.DateFormat.

Оператор typeof

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

const show = (value, type)=>console.log(`typeof (${value}) is ${type}`);

const whatIsMyTypeName = (value)=>{
  switch(typeof value){
  case 'boolean':
  case 'number':
  case 'string': return show(value, typeof value);
  default: show(value, 'выясним позднее')
  }
}

whatIsMyTypeName(true); // typeof (true) is boolean"
whatIsMyTypeName(42); // "typeof (42) is number"
whatIsMyTypeName('миру-мир!'); // "typeof (миру-мир!) is string"
whatIsMyTypeName({}); // "typeof ([object Object]) is выясним позднее"
whatIsMyTypeName(window); // "typeof ([object Window]) is выясним позднее"

Встроенные типы

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

Array (массивы)

Сразу обратите внимание, что слово Array мы употребляем с большой буквы, в то время как booleannumberstring — с маленькой.

Если вы разработчик на JavaScript, то методы работы с массивами нужно знать и уметь вспомнить, даже если вас разбудили посреди ночи. Проверьте, что вы знаете о существовании методов массива length, from, map, sort, reduce, filter, find, indexOf, findIndex

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

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

const show = (index, value)=> console.log(`${index}: ${value}`);
const items = [
'Chrome',
'Opera',
'Edge'
];

// Предоставляет элемент
show(1,items[1]) // "1: Opera"
// Ошибки нет, но и элемента тоже
show(100, items[100]); "100: undefined"

// Как, впрочем, и здесь
show(-1, items[-1]);// "-1: undefined"

items[12] = 'safari';
items[-1] = 'IE';

// Ошибки нет, а элемент появился
show(12, items[12]);//"12: safari"
show(-1, items[-1]);// "-1: IE"

// а где IE?
show('all', items)"all: Chrome,Opera,Edge,,,,,,,,,,safari"

// А тут всё ещё есть
show(-1, items[-1]);// "-1: IE"

Совет: контролируйте индексы, знайте размер массивов, с которыми работаете.

Set

Тип данных Set позволяет вам хранить набор уникальных элементов. Этим он отличается от массива. При работе с массивом вам придется предпринимать специальные усилия для поддержания уникальности элементов, Set сделает это за вас. В отличии от массива Set не позволяет произвольный доступ к элементу. Вы можете проверить наличие и получить список в порядке вставки.

const items = new Set(Array.from ({length:12},(_,ix)=>ix));

const str = (value)=>`${value}`;
const compare = (left,right)=>left<right?-1:right<left?1:0;
const byNumbericalValue = (left,right)=>compare(left,right);
const byStringValue =(left,right)=>compare(str(left),str(right));

console.log([...items].sort(byNumbericalValue));
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

console.log([...items].sort(byStringValue));
// [0, 1, 10, 11, 2, 3, 4, 5, 6, 7, 8, 9]

items.add(100);
items.add(20);

//порядок, в котором JavaScript отдает содержимое Set, зависит от порядка добавления элементов
console.log([...items].sort(byNumbericalValue));
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 20, 100]

console.log([...items].sort(byStringValue));
// [0, 1, 10, 100, 11, 2, 20, 3, 4, 5, 6, 7, 8, 9]

console.log([...items]);
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 100, 20]

Совет: для вывода элементов из Set в нужном порядке позаботьтесь о функции сортировки.

Кастомные объекты {} — ассоциативный массив

JavaScript объекты — это словари, где строковому ключу поставлен в соответствие элемент-значение. Возможны два синтаксиса доступа к значению ключа

const dictionary = {
  'language':'javascript',
  'type': 'structured',
  'age': 25
}

console.log(dictionary.language); // javascript
console.log(dictionary['language']); // javascript
const key = 'language';
console.log(dictionary[key]); // javascript

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

Это ограничение не позволяет использовать объекты для создания связей между HTML-элементами и дополнительными данным, нужными для работы программы. Для этого используйте тип Map.

Map

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

const DictionaryCO = {}; // инициализируем вариант ассоциативного массива на основе обычного объекта
const DictionaryMap = new Map(); // инициализируем вариант ассоциативного массива на основе встроенного типа Map

// Первый эксперимент будет связывать ключ 'k1' и значение 'v1'
const aKey = 'k1';
const aValue = 'v1';

// Второй эксперимент будет связывать ключ в виде объекта и значение - строку
// такой вариант в жизни встречается если для нескольких HTML элементов нужно ввести дополнительные данные, которые нельзя положить в data-xxx атрибут
const bKey = {x:1};
const bValue = 'v2';
// Третий эксперимент покажет нам недостатки ассоциативного массива на основе обычного объекта. Мы используем в качестве ключа - другой объект
const cKey = {y:2};
const cValue = 'v3';

// заполняем первый ассоциативный массив (который в виде объекта)
DictionaryCO[aKey] = aValue;
DictionaryCO[bKey] = bValue;
DictionaryCO[cKey] = cValue;

// заполняем второй ассоциативный массива (которы в виде Map)
DictionaryMap.set(aKey, aValue);
DictionaryMap.set(bKey, bValue);
DictionaryMap.set(cKey, cValue);

console.log('a object', DictionaryCO[aKey]); // "a object", "v1"
console.log('b object', DictionaryCO[bKey]); // "b object", "v2"
// хотя мы пытаемся получить значение по ключу cKey, почему-то
// мы получаем значение, которое связали с ключом bKey
console.log('c object, oops!', DictionaryCO[cKey]); // "c object, oops!", "v2"

console.log('a map', DictionaryMap.get(aKey)); // "a map", "v1"
console.log('b map', DictionaryMap.get(bKey)); // "b map", "v2"
// в этом варианте ассоциативного массива все сработало так, как мы и ожидали
console.log('c map', DictionaryMap.get(cKey)); // "c map", "v3"

Собственные структуры данных

Утиная типизация

Программисты работают с лозунгом «Algorithms + Data Structures = Programs». При работе с JavaScript разработчик преобразует требования заказчика в алгоритмы и структуры данных. Примитивных типов данных, доступных в JavaScript явно недостаточно для всего разнообразия бизнес задач, поэтому приходится использовать кастомные структуры. Для приложения электронной очереди потребуется структура с номером и временем, для умного дома — структура с данными о температуре чайника, заполненности холодильника и т. п.

let cusomerInQueue = {
  numberOnScreen: 'A42',
  timeTaken: '11:40'
}

let smartHouseState = {
  kettler: 80,
  fridge:{
    milk: true,
    banana: false,
  },
}

В вашей программе вы получаете сведения о заполнении холодильника, потому что ожидаете наличия поля fridge в структуре объекта, а не потому, что переменная называется smartHouseState. Выяснив, что в структуре объекта нет поля fridge вы смело можете сказать, что значение переменной cusomerInQueueне связано с управлением умным домом, и наоборот наличие такого поля в переменной smartHouseState подсказывает вам, что её значение описывает умный дом. Такой подход, когда о назначении значения вы судите по его структуре, называется структурной типизацией.

Иногда вы знаете структуру значения (потому что знаете), а иногда вам приходится как-то догадываться. Но как, ведь typeof в этой ситуации не поможет?

Object.keys и другие шпионские средства

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

Основными помощниками в исследовании полученных данных вам будут

  • Статический метод Object.keys
  • Оператор typeof
  • Оператор instanceof
  • Статический метод Object.hasOwn
const someValue = {
  title: 'Cruella',
  release: new Date(2021,05,03),
  empty: undefined,
}

console.log('all keys', Object.keys(someValue));
// "all keys", ["title", "release", "empty"]

console.log('typeof key release', typeof someValue.release);
// "typeof key release", "object"

console.log('instance of Date', someValue.release instanceof Date)
// "instance of Date", true

console.log('missing value', typeof someValue.empty);
// "missing value", "undefined"

console.log('missing key', Object.hasOwn(someValue, 'missing'));
// "missing key", false

Проблемы типов JavaScript

Динамическая структурная типизация JavaScript имеет давнюю историю и восходит к идее создания небольших обработчиков событий в статических HTML страницах. С тех пор все поменялось, и динамическая типизация становится серьезным риском при постепенном и постоянном совершенствовании приложения.

Например, у нас была функция transform. Мы обнаружили, что она ломается при получении значения null.

const transform = (value) => value.replace('с', 'б');

let data = 'соль'

console.log(transform(data).toUpperCase()) // "БОЛЬ"
data = null;
try {
  console.log(transform(data).toUpperCase()) // не выполнится
} catch (err) {
  console.log(err.message) // "Cannot read properties of null (reading 'replace')"
}

Исправили программу в одном месте — она начала ломаться в другом. Как разорвать замкнутый круг?

const transform2 = (value) => {
  if (typeof value === 'string') {
    return value.replace('с', 'б');
  }
}
data = 'соль';
console.log(transform2(data).toUpperCase()) // "БОЛЬ"
data = null
try {
  console.log(transform2(data).toUpperCase())
} catch (err) {
  console.log(err.message) // "Cannot read properties of undefined (reading 'toUpperCase')"
}

Вам поможет TypeScript! Но об этом в следующий раз.

Узнать больше


«Доктайп» — журнал о фронтенде. Читайте, слушайте и учитесь с нами.

ТелеграмПодкастБесплатные учебники

Читать дальше

Ошибка JavaScript «Uncaught TypeError: Cannot read property of undefined». Что делать?

Описание проблемы
Эта ошибка возникает, когда вы пытаетесь получить доступ к свойству объекта, который в данный момент имеет значение undefined. Например:


let obj = undefined;
console.log(obj.property); // Uncaught TypeError: Cannot read property 'property' of undefined
  

Возможные причины

  • Объект не был инициализирован. Возможно, переменная еще не была объявлена или ей не присвоено значение.
  • Неправильный путь к данным. Вы пытаетесь обратиться к свойству объекта, но объект отсутствует в цепочке.
  • Асинхронность. Данные могли еще не загрузиться или быть доступны в момент обращения.
  • Опечатка в названии свойства. Вы могли неверно написать имя свойства объекта.

Шаги по исправлению

1. Проверка объекта перед доступом к свойствам

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

if (obj !== undefined && obj !== null) {
    console.log(obj.property);
}

// Или современный способ:
console.log(obj?.property); // Вернет undefined, если obj равен null или undefined
  

2. Инициализация объекта перед использованием

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

Неверный код:

let data;
console.log(data.user.name); // Ошибка
  

Исправление:


let data = { user: { name: "Иван" } };
console.log(data.user.name); // "Иван"
  

3. Проверка API или данных с сервера

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

fetch('https://api.example.com/data')
    .then(response => response.json())
    .then(data => {
        if (data?.user?.name) {
            console.log(data.user.name);
        } else {
            console.error('Данные пользователя отсутствуют');
        }
    });

4. Использование значений по умолчанию

Для предотвращения ошибок можно задавать значения по умолчанию.

let user = undefined;
let userName = user?.name || "Гость";
console.log(userName); // "Гость"

5. Отладка с помощью console.log

Проверяйте промежуточные значения переменных в консоли браузера.

console.log(obj); // Убедитесь, что объект определен 

Пример из жизни
Вы пишете код для отображения имени пользователя из объекта user:

let user = null; // Данные еще не загружены
console.log(user.name); // Uncaught TypeError: Cannot read property 'name' of null

Исправление:

let user = null;
console.log(user?.name || "Имя пользователя не найдено"); // "Имя пользователя не найдено"

Итог
Следуя этим рекомендациям, вы сможете избежать ошибок, связанных с доступом к свойствам undefined или null. Если ошибка продолжает появляться, убедитесь, что данные корректно загружаются, и используйте инструменты отладки.

JS
  • 15 ноября 2024

Как исправить ошибку JavaScript «Uncaught ReferenceError: variable is not defined»

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

console.log(myVariable); // Uncaught ReferenceError: myVariable is not defined

Возможные причины

  • Вы пытаетесь обратиться к переменной до ее объявления.
  • Переменная объявлена внутри функции и недоступна за ее пределами.
  • Ошибка в написании имени переменной (опечатка).

Шаги по исправлению

1. Проверка объявления переменной

Убедитесь, что переменная объявлена перед ее использованием.

Неверный код:

console.log(myVariable); // Ошибка

Исправление:

let myVariable = 10;
console.log(myVariable); // 10

2. Правильное определение области видимости переменной

Если переменная объявлена внутри функции, она недоступна за ее пределами.

Неверный код:

function myFunction() {
    let localVariable = "Привет";
}
console.log(localVariable); // Ошибка

Исправление:

function myFunction() {
    let localVariable = "Привет";
    console.log(localVariable); // "Привет"
}
myFunction();

3. Использование глобальных переменных

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

let globalVariable = "Глобальная переменная";
function showVariable() {
    console.log(globalVariable);
}
showVariable(); // "Глобальная переменная"

4. Проверка имени переменной на ошибки

Проверьте, нет ли опечаток в имени переменной.

Неверный код:

let myVariable = "Данные";
console.log(myVarible); // Ошибка

Исправление:

let myVariable = "Данные";
console.log(myVariable); // "Данные"

5. Использование typeof для проверки существования переменной

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

if (typeof myVariable !== "undefined") {
    console.log(myVariable);
} else {
    console.log("Переменная не определена");
}

Пример из жизни
Вы пишете функцию для проверки данных пользователя:

function checkUser() {
    if (userName) {
        console.log(`Добро пожаловать, ${userName}!`);
    }
}
checkUser(); // Ошибка: userName не определен

Исправление:

let userName = "Иван";
function checkUser() {
    if (userName) {
        console.log(`Добро пожаловать, ${userName}!`);
    }
}
checkUser(); // "Добро пожаловать, Иван!"

Итог
Эта ошибка часто возникает из-за опечаток или неверной области видимости. Убедитесь, что переменные объявлены и доступны в нужных местах. Если необходимо, используйте typeof для проверки их существования.

JS
  • 15 ноября 2024

Как исправить ошибку JavaScript «Uncaught TypeError: Cannot set property of undefined»

Эта ошибка возникает, когда вы пытаетесь присвоить значение свойству объекта, который не существует (имеет значение undefined или null). Например:

let obj;
obj.property = "value"; // Uncaught TypeError: Cannot set property 'property' of undefined

Возможные причины

  • Объект не был инициализирован.
  • Вы обращаетесь к объекту, который уже удален или еще не создан.
  • Ошибка в цепочке данных, например, промежуточное свойство объекта равно undefined.

Шаги по исправлению

1. Инициализация объекта перед использованием

Убедитесь, что объект объявлен и инициализирован перед тем, как вы присваиваете его свойствам значения. Неверный код:

let obj;
obj.property = "value"; // Ошибка

Исправление:

let obj = {};
obj.property = "value"; // Работает

2. Проверка существования объекта перед доступом

Проверяйте объект на null или undefined, чтобы избежать ошибок. Пример:

let obj;
if (obj) {
    obj.property = "value";
} else {
    console.log("Объект не определен");
}

3. Использование опциональной цепочки

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

let obj;
obj?.nestedProperty?.subProperty = "value"; // Не вызовет ошибку

4. Проверка асинхронных данных

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

let obj;
setTimeout(() => {
    obj = { property: "value" };
    console.log(obj.property); // Работает
}, 1000);

// Нельзя обращаться к obj до инициализации:
console.log(obj.property); // Ошибка

Пример из жизни
Вы загружаете данные пользователя с сервера и пытаетесь установить свойство объекта:

let user;
user.name = "Иван"; // Ошибка

Исправление:

let user = {};
user.name = "Иван"; // Работает

Итог
Чтобы избежать ошибки «Cannot set property of undefined», убедитесь, что объект существует и инициализирован. Используйте проверки на null, опциональную цепочку или инициализируйте объект перед работой с его свойствами.

JS
  • 15 ноября 2024

Как исправить ошибку JavaScript «Uncaught SyntaxError: Unexpected token»

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

let obj = { key: "value", }; // Uncaught SyntaxError: Unexpected token }

Возможные причины

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

Шаги по исправлению

1. Проверка корректности синтаксиса

Убедитесь, что все запятые, точки с запятой и кавычки находятся на своих местах. Неверный код:

let obj = { key: "value", }; // Лишняя запятая

Исправление:

let obj = { key: "value" }; // Правильный синтаксис

2. Проверка закрытия скобок

Проверьте, закрыты ли все фигурные, круглые и квадратные скобки. Неверный код:

if (true {
    console.log("Ошибка!");
}

Исправление:

if (true) {
    console.log("Исправлено!");
}

3. Проверка типов кавычек

Не смешивайте одинарные и двойные кавычки. Неверный код:

let str = "Привет'; // Ошибка

Исправление:

let str = "Привет"; // Или let str = 'Привет';

4. Использование отладчика

Откройте консоль браузера или отладчик в вашей IDE, чтобы найти строку с ошибкой. Она будет указана в сообщении об ошибке.

// В консоли может быть указано:
Uncaught SyntaxError: Unexpected token } at script.js:10

Исправьте строку, где произошла ошибка.

5. Проверка работы кода в строгом режиме

Добавьте "use strict"; в начало вашего файла или функции, чтобы браузер проверял ваш код на соответствие строгому синтаксису.

"use strict";
let obj = { key: "value" };
console.log(obj);

Пример из жизни
Вы пытаетесь использовать стрелочную функцию, но забыли закрыть скобки:

const add = (a, b => {
    return a + b;
};

Исправление:

const add = (a, b) => {
    return a + b;
};

Итог
Чтобы избежать ошибок «Unexpected token», всегда проверяйте синтаксис вашего кода на наличие лишних или пропущенных символов, используйте инструменты отладки и следите за правильным использованием конструкций JavaScript.

JS
  • 15 ноября 2024
9 книг по JavaScript для начинающих в 2024

9 книг по JavaScript для начинающих в 2024

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

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

Читать дальше
JS
  • 6 марта 2024
Объект URL в JavaScript: полный разбор

Объект URL в JavaScript: полный разбор

Объект URL в JavaScript представляет URL-адрес и предоставляет удобные методы для работы с ним. Он позволяет анализировать, конструировать и декодировать URL-адреса.

Создать объект URL можно двумя способами:

Конструктор URL() — самый распространённый способ, в котором вы передаёте любой URL в виде строки в качестве аргумента.

const url = new URL("https://www.example.com/path?query=123#hash");

Использование window.location — это глобальный объект в браузерах, который содержит информацию о текущем URL.

const currentUrl = new URL(window.location.href);
Читать дальше
JS
  • 23 января 2024
Знакомство с JavaScript

Знакомство с JavaScript

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

Вы можете добавить JavaScript в ваш HTML-документ двумя способами:

Встроенный JavaScript: непосредственно в HTML-документ, в тегах <script>:

<script>
  alert("Привет, мир!");
</script>

Внешний JavaScript: подключение внешнего .js файла к HTML-документу:

<script src="script.js"></script>
Читать дальше
JS
  • 1 ноября 2023