Автор: Теняев Виктор Сергеевич, Шевчук Александра Сергеевна
1. Что такое объекты и массивы в JavaScript
Объекты
Используются для хранения коллекций различных значений и более сложных сущностей.
Массивы
Существует два варианта синтаксиса для создания пустого массива:
let arr = new Array();
let arr = [];
Практически всегда используется второй вариант синтаксиса. В скобках мы можем указать начальные значения элементов:
let fruits = ["Яблоко", "Слива", "Апельсин"];
Элементы массива нумеруются, начиная с нуля.
2. Основные отличия объектов от массивов:
Объекты позволяют хранить данные со строковыми ключами, но довольно часто мы понимаем, что нам необходима упорядоченная коллекция данных, в которой присутствуют 1-й, 2-й, 3-й элементы и т.д. К примеру, она понадобится нам для хранения списка чего-либо: пользователей, товаров, элементов HTML и т.д.
В этом случае использовать объект неудобно, так как он не предоставляет методов управления порядком элементов. Объекты просто не предназначены для этих целей.
Поэтому для хранения упорядоченных коллекций существует особая структура данных, которая называется массив, Array.
3. Когда использовать объекты, а когда массивы
Используйте объекты в следующих случаях:
-
Когда порядок значений не важен
-
Когда ключи – это строки, к примеру user.name
-
Когда нужно хранить ключ-значение
-
Когда данные представляют сущность с характеристиками
Используйте массивы в следующих случаях:
-
Когда нужно хранить упорядоченный список элементов
-
Когда порядок имеет значение
-
Когда доступ к элементам происходит по индексу
-
Когда существует коллекция однотипных элементов
Пример, показывающий когда удобно использовать объект, а когда массив:
<!DOCTYPE html>
<html lang="ru">
<body>
<div id="output"></div>
<script>
const user = { name: "Анна", age: 25 };
const items = ["Хлеб", "Молоко", "Яблоки"];
document.getElementById("output").innerHTML =
`Пользователь: ${user.name}, ${user.age} лет <br> Покупки: ${items.join(", ")}`;
</script>
</body>
</html>
Объекты в JavaScript
1. Что такое объект и как его создать?
Объект — это тип данных, который используется для хранения коллекций различных значений и более сложных сущностей.
Объект может быть создан с помощью фигурных скобок {…} с необязательным списком свойств. Свойство – это пара «ключ: значение», где ключ – это строка (также называемая «именем свойства»), а значение может быть чем угодно.
2. Синтаксис создания объекта
Пустой объект можно создать, используя один из двух вариантов синтаксиса:
let user = new Object(); // синтаксис 'конструктор объекта
let user = {}; // синтаксис 'литерал объекта
При использовании литерального синтаксиса {…} мы сразу можем поместить в объект несколько свойств в виде пар «ключ: значение»:
let user = {
name: 'John', // под ключом 'name' хранится значение 'John'
age: 30 //под ключом 'age' хранится значение 30
};
У каждого свойства есть ключ (также называемый «имя» или «идентификатор»).
В объекте user сейчас находятся два свойства:
-
Первое свойство с именем “name” и значением “John”.
-
Второе свойство с именем “age” и значением 30.
Доступ к свойствам (object.property, object[‘property’])
Для обращения к свойствам используется запись «через точку»:
получаем свойства объекта
alert(user.name); // John
alert(user.age); // 30
Для свойств, имена которых состоят из нескольких слов, доступ к значению «через точку» не работает:
это вызовет синтаксическую ошибку
user.likes birds = true
Для таких случаев существует альтернативный способ доступа к свойствам через квадратные скобки.
let user = {}
присвоение значения свойству
user['likes birds'] = true;
HasOwnProperty и in — это два способа проверки наличия свойства в объекте, но между ними есть важные различия:
HasOwnProperty:
- проверяет только собственные свойства.
In:
- проверяет все свойства, включая унаследованные.
- Добавление, изменение и удаление свойств
Добавление свойств:
user.isAdmin = true;
Удаление свойств:
Для удаления свойств используется оператор delete
delete user.age;
Изменение свойств:
user.name = 'Pete';
- Методы объектов (this, Object.keys(), Object.values(), Object.entries())
Методу объекта обычно требуется доступ к информации, хранящейся в объекте, для выполнения своей работы. Для доступа к информации внутри объекта метод может использовать ключевое слово this.
Значение this – это объект «перед точкой», который используется для вызова метода.
Например:
let user = {
name: 'John',
age: 30,
sayHi() {
// 'this' - это текущий объект
alert(this.name);
}
};
user.sayHi(); John
Технически также возможно получить доступ к объекту без ключевого слова this, обратившись к нему через внешнюю переменную:
let user = {
name: 'John',
age: 30,
sayHi() {
alert(user.name); // 'user' вместо 'this'
}
};
Но такой код ненадежен.
Object.keys() возвращает массив, элементами которого являются строки, соответствующие перечисленным именам свойств с ключами-строками, найденным непосредственно в object. Порядок элементов массива, возвращаемого Object.keys(), совпадает с порядком, обеспечиваемым циклом for…in.
Если вам нужны значения свойств, используйте Object.values() вместо этого. Если вам нужны и ключи свойств, и значения, используйте Object.entries() вместо этого.
Пример:
const object1 = {
a: 'somestring',
b: 42,
c: false,
};
console.log(Object.keys(object1));
// expected output: Array ['a', 'b', 'c']
Статический метод Object.entries() возвращает массив собственных перечисляемых пар «ключ-значение» со строковыми ключами для заданного объекта.
Пример:
const object1 = {
a: 'somestring',
b: 42,
};
for (const [key, value] of object.entries(object1)) {
console.log('${key}: $value}');
}
// expected output
// 'a: somestring
// 'b: 42
Статический метод Object.values() возвращает массив собственных перечисляемых значений свойств с ключами в виде строк.
Пример:
const object1 = {
a: 'somestring,
b: 42,
c: false,
};
console.log(Object.values(object1));
// expected output: Array ['somestring', 42, false]
Массивы в JavaScript
1. Что такое массив и как его создать
Массив — это особая структура данных для хранения упорядоченных коллекций.
Существует два варианта синтаксиса для создания пустого массива:
let arr = new Array();
let arr = [];
Практически всегда используется второй вариант синтаксиса:
let fruits = ['Яблоко', 'Апельсин', 'Слива'];
2. Методы работы с массивами(push, pop, shift, unshift, splice, slice)
1) pop
Удаляет последний элемент из массива и возвращает его:
let fruits = ['Яблоко', 'Апельсин', 'Груша'];
alert(fruits.pop()); // удаляем грушу и выводим ее
alert(fruits); Яблоко, Апельсин
2) push
Добавляет элемент в конец массива:
let fruits = ['Яблоко', 'Апельсин'];
fruits.push('Груша');
alert(fruits); Яблоко, Апельсин, Груша
3) shift
Удаляет из массива первый элемент и возвращает его:
let fruits = ['Яблоко', 'Апельсин', 'Груша'];
alert(fruits.shift()); // удаляем яблоко и выводим ее
alert(fruits); // Апельсин, Груша
4) unshift
Добавляет элемент в начало массива:
let fruits = ['Апельсин', 'Груша'];
fruits.unshift('Яблоко');
alert(fruits); // Яблоко, Апельсин, Груша
5) splice
Это универсальный «швейцарский нож» для работы с массивами. Умеет всё: добавлять, удалять и заменять элементы.
arr.splice(start[, deleteCount, elem1, …])
Удаление:
let arr = ['Я', 'изучаю', 'JavaScript'];
arr.splice(1,1); // начиная с индекса 1, удалить 1 элемент
alert(arr); // осталось ['Я', 'JavaScript']
splice возвращает массив из удалённых элементов:
let arr = ['Я', 'изучаю', 'JavaScript', 'прямо', 'сейчас'];
// удалить 2 первых элемента
let removed = arr.splice(0,2);
alert(removed); // 'Я', 'изучаю' ← массив из удаленных элементов
Метод splice также может вставлять элементы без удаления, для этого достаточно установить deleteCount в 0:
let arr = ['Я', 'изучаю', 'JavaScript'];
arr.splice(2, 0, 'сложный', 'язык');
alert(arr); 'Я', 'изучаю', 'сложный', 'язык', 'JavaScript'
6) slice
Синтаксис:
arr.sle=ice([start], [end])
Он возвращает новый массив, в который копирует все элементы с индекса start до end (не включая end).
let arr = ['t', 'e', 's', 't'];
alert(arr.slice(1,3)); // e, s (копирует с 1 до 3)
alert(arr.slice(-2)); // s, t (копирует с -2 до конца)
Можно вызвать slice без аргументов: arr.slice() создаёт копию arr. Это часто используют, чтобы создать копию массива для дальнейших преобразований, которые не должны менять исходный массив.
3. Перебор массива с помощью for, for of, и forEach
Одним из самых старых способов перебора элементов массива является цикл for по цифровым индексам:
let arr = ['Яблоко', 'Апельсин', 'Груша'];
for (let i = 0; i < arr.length; i++) {
alert(arr[i]);
}
Но для массивов возможен и другой вариант цикла, for..of:
let arr = ['Яблоко', 'Апельсин', 'Груша'];
// проходит по значениям
for (let fruit of fruits) {
alert(fruit);
}
Цикл for..of не предоставляет доступа к номеру текущего элемента, только к его значению, но в большинстве случаев этого достаточно.
Метод arr.forEach позволяет запускать функцию для каждого элемента массива.
Синтаксис:
arr.forEach(function(item, index, array) {
// делать что-то с item
});
Например, этот код выведет на экран каждый элемент массива:
Вызов alert для каждого элемента
['Бильбо', 'Гэндальф', 'Назгул'].forEach(alert);
4. Работа с многомерными массивами
Многомерный массив — это массив, в котором содержится другой массив или другие массивы.
пример многомерного массива
const data = [[1, 2, 3], [1, 3, 4], [4, 5, 6]];
Получить элемент многомерного массива можно обратившись к нему по индексу или индексам:
let x = [
['Андрей', 24],
['Настя', 23],
['Даня', 24]
];
получаем первый элемент - это массив
console.log(x[0]); // Вывод: ['Андрей', 24],
получаем первый элемент первого внутреннего массива
console.log(x[0][0]); // Вывод: Андрей
получаем второй элемент третьего внутреннего массива
console.log(x[2][1]); // Вывод: 24
Добавление элементов в многомерный массив:
Добавить элемент в многомерный массив можно с помощью метода push() или с помощью квадратных скобок [] и доступа по индексу.
Добавление элемента во внешний массив с помощью push():
let studentsData = [['Андрей',24], ['Настя', 23]];
studentsData.push(['Даня', 24]);
С помощью квадратных скобок:
let studentsData = [['Андрей',24], ['Настя', 23]];
studentsData[1][2] = 'привет';
console.log(studentsData); Вывод: [['Андрей',24], ['Настя', 23, 'привет']];
Удаление элементов из многомерного массива:
С помощью pop():
let studentsData = [['Андрей',24], ['Настя', 23]];
studentsData.pop();
console.log(studentsData); Вывод: [['Андрей',24]]
С помощью splice():
let studentsData = [['Андрей',24], ['Настя', 23]];
// удаляем элемент внешнего массива с индексов 1 - внутренний массив
studentsData.splice(1, 1);
console.log(studentsData); // Вывод: [['Андрей',24]]
Перебор элементов многомерного массива:
C помощью forEach():
let studentsData = [['Андрей',24], ['Настя', 23]];
studentsData.foreach((students)=> {
student .forEach((data)=> {
console.log(data);
});
});
С помощью For..of:
let studentsData = [['Андрей',24], ['Настя', 23]];
for (let j of i) {
for (let j of i) {
console.log(j);
}
}
C помощью for:
let studentsData = [['Андрей',24], ['Настя', 23]];
// проходим по элементам внешнего массива
for(let i = 0; i < studentsData.length; i++) {
// вычисляем длину внутреннего массива
let innerArrayLength = studentsData[i].length;
// проходим по элементам внутреннего массива
for (let j = 0; j < innerArrayLength; j++) {
console.log(studentsData[i][j]);
}
}
Метод map и работа с массивами
- Что делает map, когда его использовать
Map- это метод преобразования и упорядочения массива. Он вызывает функцию для каждого элемента массива и возвращает массив результатов выполнения этой функции.
- Синтаксис и примеры использования
Как пишется
Функция, которую мы передаем в метод map(), может принимать три параметра:
arr - сам массив, который мы перебираем;
index - индекс текущего элемента;
item - элемент массива в текущей итерации.
const nums = [0, 1, 2, 3]
const transformed = nums.map(function(num, index, arr) {
return num+index+arr.length
})
console.log(transformed) // [4, 6, 8, 10]
*В данном примере мы суммируем числа, индексы и длины массива
Пример использования
const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9]
const squares = nums.map(function(num){
return num * num
})
console.log(squares) // [1, 4, 9, 16, 25, 36, 49, 64, 81]
*Создан массив квадратов чисел
- Сравнение map с forEach
Оба метода принимают колбэк, который вызывается для каждого элемента. Разница в том, что метод forEach() ничего не возвращает, а метод map() возвращает новый массив с результатами вызова колбэка на каждом исходном элементе.
Используя map() вы можете создавать цепочки вызовов. Если же вы будете использовать forEach() так сделать не получится:
map:
const myArray = [4, 2, 8, 7, 3, 1, 0];
const myArray2 = myArray.map(item => item *2).sort((a, b) => a -b);
console.log(myArray); // [4, 2, 8, 7, 3, 1, 0]
console.log(myArray2); // [0, 2, 4, 6, 8, 14, 16]
Здесь изменился только myArray2.
ForEach:
const myArray = [4, 2, 8, 7, 3, 1, 0];
let myArray2 = [];
myArray.forEach(item => {
myArray2.push(item*2);
});
myArray2=myArray2.sort((a,b) => a - b);
console.log(myArray); // [4, 2, 8, 7, 3, 1, 0]
console.log(myArray2); // [0, 2, 4, 6, 8, 14, 16]
- Комбинирование map с другими методами массивов (filter, reduce)
filter:
Метод массива .filter() позволяет получить новый массив, отфильтровав элементы с помощью переданной колбэк-функции. Колбэк-функция будет вызвана для каждого элемента массива и по результату функции примет решение включать этот элемент в новый массив или нет.
Пример:
let numbers = [1, 2, 3, 4, 5, 6];
let doubledEvens = numbers
.filter(num => num % 2 === 0) // Оставляем только четные числа
.map(num => num * 2); // Умножаем их на 2
console.log(doubledEvens); // [4, 8, 12]
filter выбирает четный числа, а map уможает их на 2
reduce:
Метод массива reduce() позволяет превратить массив в любое другое значение с помощью переданной функции-колбэка и начального значения. Функция-колбэк будет вызвана для каждого элемента массива, и всегда должна возвращать результат.
Пример:
let prices = [100, 200, 300, 400];
let totalWithDiscount = prices
.map(price => price * 0.9) // Применяем 10% скидку
.reduce((total, price) => total + price, 0); // Складываем все цены
console.log(totalWithDiscount); 900
- Сначала map уменьшает каждую цену на 10%, а потом reduce суммирует их
flat
Используется для «разглаживания» (разворачивания) вложенных массивов.
const arr = [1, [2, [3, [4]]]];
console.log(arr.flat(1)); // [1, 2, [3, [4]]]
console.log(arr.flat(2)); // [1, 2, 3, [4]]
console.log(arr.flat(Infinity)); // [1, 2, 3, 4]
flatMap
Комбинирует map и flat(1), применяя функцию к каждому элементу и упрощая результат.
const arr = [1, 2, 3];
const result = arr.flatMap(x => [x, x * 2]);
console.log(result); // [1, 2, 2, 4, 3, 6]
reduceRight
Работает как reduce, но проходит по массиву справа налево.
const arr = [1, [2, [3, [4]]]];
const flattened = arr.reduceRight((acc, val) => acc.concat(Array.isArray(val) ? val.flat(Infinity) : val), []);
console.log(flattened); [1, 2, 3, 4]
Объекты и массивы в практике
- Как хранить массив объектов
Массив объектов- это обычный массив, в котором каждый элемент является объектом.
Для хранения массива объектов в LocalStorage нужно преобразовать его в строку, используя JSON.stringify, так как LocalStorage хранит данные в строчном формате.
- LocalStorage- это один из способов хранить данные в браузере.
Пример:
var users = [
{name: 'Alex', age: 20},
{name: 'Oleg', age: 30}
];
localStoragw.setltem('storedUsers', JSON.stringify(users)); Сохранение в localStorage
var users = [];
if (localStorage.getltem('storedUsers')) {
users = JSON.parse(localStorage.getltem('storedUsers')); // Извлечение из localStorage
}
- Как изменять объекты внутри массива (map, find, filter)
-
map:
Данный метод вызывает функцию для каждого элемента массива и возвращает массив результатов выполнения этой функции.
Пример:
let lengths = ['Бильбо', 'Гэндальф', 'Назгул'].map(item => item.length);
alert(lengths); // 6, 8, 6
// Преобразуем каждый элемент в его длину
-
find:
Этот метод массива вернет первый найденный в массиве элемент, который подходит под условие в переданной колбэк-функции.
Синтаксис:
Функция, которую мы передаём в метод find, принимает три параметра:
-
element - элемент массива в текущей итерации;
-
index - индекс текущего элемента;
-
arr - сам массив, который мы перебираем.
Пример:
const is0dd = (element) => {
return element % 2 === 1
}
-
filter:
filter возвращает массив из всех подходящих элементов: Пример:
let users = [
{id: 1, name: 'Вася'},
{id: 1, name: 'Петя'},
{id: 1, name: 'Маша'}
];
// возвращает массив, состоящий из двух пользователей
let someUsers = users.filter(item => id < 3);
alert(someUsers.length); 2
- Пример использования объектов и массивов в реальных задачах
Реальный пример: нужно сделать to-do-list
Выполнение:
let tasks = [
{ id: 1, description: '', completed: false},
{ id: 2, description: '', completed: true}
];
Добавление новой задачи
tasks.push({ id: 3, description: '', completed: false});
Обновление статуса задачи
tasks = tasks.map(task => {
if (tasks.map(task => {
return { ...task, completed: true};
}))
return task;
});
Фильтрация выполненных задач
let completedTasks = tasks.filter(task => task.completed);
Массив объектов используется для хранения списка задач, а методы массива для добавления новых задач, обновления их статуса и фильтрации по критериям