Типы данных в JavaScript
Оглавление:
Что такое JavaScript и как хранятся данныеПримитивные типы
Встроенные типы
Работа с наборами
Проблемы типов в JavaScript
Заключение
JavaScript — язык программирования, который используют для создания интерактивных элементов на сайтах. Изучив его, разработчик сможет реализовать мини-игры, анимированные кнопки, динамические стили. Одной из основ являются типы данных. В этой статье разберем, как хранится информация в JavaScript, какие виды данных существуют.
Что такое JavaScript и как хранятся данные
JavaScript — динамический язык программирования, который применяют к разметке HTML для обеспечения интерактивности. Его разработал Брендан Эйч, сооснователь Mozilla Corporation. Зная JS, программисты могут создавать игры, 2D и 3D графику, веб-приложения и т. д.
Информация в JavaScript хранится в двух хранилищах:
- стек — статическое выделение памяти;
- куча — динамическое выделение памяти.
Примитивные типы
В JS существует 7 примитивных типов. Их используют с первых уроков по языку программирования, поэтому важно их детально изучить. Из примитивных данных кратко рассмотрим:
- symbol — нужен для создания уникальных идентификаторов для других объектов;
- null — для неизвестных объектов;
- bigint — тип для работы с большими числами.
О других типах стоит рассказать подробнее.
Undefined
Значение объявленной, но еще неинициализированной переменной. Undefined появляется, если программа обращается к информации, которой еще нет. Это значение появляется по умолчанию, если программист не указал что-то другое.
Особенность JavaScript — иногда Undefined появляется, даже если присвоить переменной значение. Это возникает, когда функция должна присвоить данные ключевому слову return, но его нет. Если не инициализировать возвращаемое из функции значение, тогда на выходе программист получает Undefined.
Пример:
function trukComputation (){
let a = 0;
while(a<4){
a+=1;
}
}
let buffer = trukComputation()
Нужно внимательно работать со значениями переменных, чтобы программа работала правильно.
Boolean
Принимает только логические константы True или False. Этот тип нужен для проверки значений на соответствие требованиям.
Рассмотрим следующий метод для проверки правдивости:
const showPravda = (n,value)=> console.log(`${n} - ${value?'true':'false'}`);
Следующие примеры точно окажутся ложными:
showPravda(1, false); // false
showPravda(2, ''); // false
showPravda(3, 0) // false
Однако не всегда все работает так, как можно ожидать. К примеру:
showPravda(1, []); // true
showPravda(2, {}); // true
showPravda(3, [] === []); // false
showPravda(4, {} === {}); // false
Пустые значения по умолчанию ложны, однако выше видно, что все работает наоборот.
А в другом примере boolean неправильно определяет одинаковость типов данных:
showPravda(1, 0 == '0'); // true
showPravda(2, 0); // false
showPravda(3, '0'); // true
В обоих случаях проблема связана с тем, что JavaScript неявно преобразовывает значения из одного вида в другой. Если вовремя не найти сбой, потом выявить ошибку тяжело. Для избежания сюрпризов стоит использовать явное преобразование типов и строгие сравнения (===) (! ==).
Number
Предназначен для моделирования действительных чисел, которых бесконечное множество. А компьютерная память ограничена, поэтому с Number часто возникают проблемы.
Сложение чисел в JavaScript отличается от школьной математики. Если вы считаете, что от перемены мест ничего не изменится, нужно заново учить фундаментальные правила JS, потому что это не всегда работает так, как хотелось бы. Пример:
showPravda(1, 1+2 === 3); // true
const lastyearCredits = Array.from ({length:30},()=>Number.EPSILON/10);
const previousyearBalance = 0.8;
const currentBalanceV1 = previousyearBalance + lastyearCredits.reduce((a,b)=>a+b,0);
const currentBalanceV2 = 0 + lastyearCredits.reduce((a,b)=>a+b,previousyearBalance);
showPravda(2, currentBalanceV1>currentBalanceV2); // true
showPravda(3, 0.1+0.2 === 0.2+0.1) // true
String
Это последовательности символов, из которых складываются строки. String — неизменяемый тип, т. е. нельзя заменить одну букву в слове без риска сбоя. Работая со строками, программисты сравнивают, складывают, преобразуют и извлекают из них конкретные символы. Нумерация букв в строке начинается с 0, поэтому программисты часто используют -1, чтобы упростить поиск нужного знака.
const show = (value)=>console.log(value);
const alphabet= 'абвгдеёжзийклмнопрстуфхцчшщъыьэюя';
show(alphabet); // "абвгдеёжзийклмнопрстуфхцчшщъыьэюя"
show(alphabet[1-1]); // "а"
show(alphabet[33-1]); //"я"
Встроенные типы
Так называют данные, которые заранее определены языком программирования. Их можно использовать без предварительного создания, поскольку интерпретатор уже знаком с ними.
Array
Массивы представляют собой списочные структуры, предназначенные для хранения упорядоченных значений. В отличие от объектов, Array имеет удобные методы оптимизации и поиска информации внутри себя. В массиве можно хранить огромное количество данных, например, каталоги, перечень пользователей и т. д.
Как создать Array:
var fruits = ['Яблоко', 'Банан'];
console.log(fruits.length);
// 2
А так разработчики запускают итерирование (перебор элементов) по массиву:
fruits.forEach(function(item, index, array) {
console.log(item, index);
Set
Set – это набор уникальных значений, т. е. каждое значение в множестве может встречаться только один раз. Это нужно для того, чтобы очистить массив от повторов, которые только занимают место. Разработчики перебирают элементы набора по порядку вставки методом add().
Пример набора и работы с ним:
for (const item of mySet1) {
console.log(item);
}
// 1, "text", { "a": 1, "b": 2 }, { "a": 1, "b": 2 }, 5
for (const item of mySet1.keys()) {
console.log(item);
}
// 1, "text", { "a": 1, "b": 2 }, { "a": 1, "b": 2 }, 5
for (const item of mySet1.values()) {
console.log(item);
}
// 1, "text", { "a": 1, "b": 2 }, { "a": 1, "b": 2 }, 5
for (const [key, value] of mySet1.entries()) {
console.log(key);
}
// 1, "text", { "a": 1, "b": 2 }, { "a": 1, "b": 2 }, 5
const myArr = Array.from(mySet1) // [1, "text", {"a": 1, "b": 2}, {"a": 1, "b": 2}, 5]
mySet1.add(document.body)
mySet1.has(document.querySelector('body')) // true
const mySet2 = new Set([1, 2, 3, 4]);
console.log(mySet2.size); // 4
console.log([...mySet2]); // [1, 2, 3, 4]
const intersection = new Set([...mySet1].filter((x) => mySet2.has(x)));
const difference = new Set([...mySet1].filter((x) => !mySet2.has(x)));
mySet2.forEach((value) => {
console.log(value);
});
// 1
// 2
// 3
// 4
Ассоциативный массив
Это массив, в котором роль ключей выполняют не целые числа, как в обычном массиве, а строки. Ассоциативный массив (также его называют словарем) работает по принципу «ключ-значение», поэтому поиск информации осуществляется по имени ключа. В отличие от обычных массивов, разработчикам и программам не нужно определять порядковый номер элемента.
Пример работы со словарем:
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
Работа с наборами
Рассмотрим несколько распространенных методов работы с наборами данных.
Объединение
Чтобы избавиться от повтором информации в разных коллекциях и собрать их в одном месте, нужно превратить наборы в массивы:
let engineering = new Set(['Alberta', 'Dr. Gero', 'Trunks', 'Bulma', 'Gohan']);
let freelancers = new Set(['Piccolo','Trunks', 'Vegeta', 'Goku', 'Gohan']);
let union = new Set([...engineering, ...freelancers]);
console.log(union);
Оператор “...” изменяет тип объекта, поэтому после объединения конструктор Set автоматически удалит все повторы. В примере выше результатом станет новый набор, который включает в себя: {'Alberta', 'Dr. Gero', 'Trunks', 'Bulma', 'Gohan', 'Piccolo', 'Vegeta', 'Goku' }.
Пересечение
Эта функция позволяет программисту извлечь общие элементы из нескольких множеств. На выходе он получит объекты, которые встречаются во всех обработанных сетах. Пример:
let a = new Set([book,pen,notebook]);
let b = new Set([pen,notebook,laptop]);
let intersection = new Set([...a].filter(x => b.has(x))); // {pen,notebook}
Разница
Допустим, программисту нужно узнать, есть ли отличия у двух наборов. После обработки пользователь получит новый массив из элементов, которые присутствуют в первом наборе, а во втором — нет.
Пример:
let engineering = new Set(['Alberta', 'Dr. Gero', 'Trunks', 'Bulma', 'Gohan']);
let freelancers = new Set(['Piccolo','Trunks', 'Vegeta', 'Goku', 'Gohan']);
let difference = new Set([...engineering].filter(x => !freelancers.has(x)));
console.log(difference);
Проблемы типов в JavaScript
Динамическая типизация данных в языке программирования имеет длинную историю и произошла от идеи создания небольших обработчиков событий на статических веб-страницах. JavaScript сильно изменился с выхода первой версии языка программирования, стал мощнее. В результате динамическая типизация стала острой проблемой при разработке больших веб-приложений.
Пример программы:
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')"
}
Функция работает с ошибками, если отправить значение null. После устранения одной проблемы появилась новая проблема:
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. Он имеет похожий синтаксис, поэтому с освоением нового языка программирования от Microsoft сложностей возникнуть не должно.
Заключение
JavaScript, как и другие языки программирования, имеет множество типов данных, которые пригодятся во время разработки интерактивных элементов, приложений и других объектов. Хотя JS прост в освоении, динамическая типизация может стать проблемой даже для профессиональных программистов.
Из-за этого часто они работают с TypeScript, который отлично подходит для веб-приложений. Он представляет собой объектно-ориентированный язык программирования и поддерживает статическую типизацию.
Также рекомендуем посмотреть пару полезных видео от наших учителей, которые на реальных примерах рассказали о JS, типах данных и работе с ними:
-
Уверенно работать с JavaScript
-
Создавать архитектуру приложения
-
Взаимодействовать с сервером
-
Создавать SPA приложения
-
Использовать HTML5 API