JavaScript. Функции, типы данных и методы работы с ними

Примечание: Это статья — конспект моей лекции. В ней описываются ключевые понятия.

Типы данных

Примитивные типы данных в JavaScript:

number: числовое значение, например, 5 или 3.14.
string: строковое значение, например, "Привет" или 'Мир'.
boolean: логическое значение, true или false.
null: специальное значение, представляющее отсутствие значения.
undefined: значение, которое не было присвоено.
symbol (в ECMAScript 6): уникальное и неизменное значение.

Объекты

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

const person = {
name: "John",
age: 30,
isAdmin: false,
greet: function() {
console.log(`Привет, меня зовут ${this.name}!`);
}
};
console.log(person.name); // Вывод: John
console.log(person.age); // Вывод: 30
person.greet(); // Вывод: Привет, меня зовут John!

Объекты могут быть созданы с использованием фигурных скобок {} и заполнены парами ключ-значение.

Доступ к свойствам объекта можно получить с помощью оператора . или квадратных скобок [].

console.log(person.name); // Вывод: John
console.log(person["age"]); // Вывод: 30

Свойства объекта могут быть добавлены или изменены после его создания.

person.country = "USA"; // Добавление нового свойства
person.age = 31; // Изменение значения существующего свойства

Свойства объекта могут быть удалены с помощью оператора delete.

delete person.isAdmin; // Удаление свойства

Свойства объекта могут быть перебраны с использованием циклов или методов перебора.

// Цикл for..in
for (let key in person) {
console.log(key + ": " + person[key]);
}
// Метод Object.keys()
const keys = Object.keys(person);
console.log(keys); // Вывод: ["name", "age", "country"]

Существование свойств в объекте можно проверить с помощью оператора in или метода hasOwnProperty.

console.log("name" in person); // Вывод: true
console.log(person.hasOwnProperty("age")); // Вывод: true

Копирование объектов может быть выполнено с использованием различных методов, таких как Object.assign(), оператор распространения (...) или конструктор Object.

// Object.assign()
const copiedPerson1 = Object.assign({}, person);
// Оператор распространения (spread operator)
const copiedPerson2 = { person };
// Конструктор Object
const copiedPerson3 = new Object(person);

Массивы

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

Массивы могут быть созданы с использованием литерала массива [] или с помощью конструктора new Array().

const numbers = [1, 2, 3, 4, 5]; // Массив чисел
const names = ['John', 'Alice', 'Bob']; // Массив строк
const mixedArray = [1, 'two', true]; // Массив смешанных типов данных
const emptyArray = []; // Пустой массив
// Создание массива с помощью конструктора
const fruits = new Array('apple', 'banana', 'orange');

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

console.log(numbers[0]); // Вывод: 1console.log(names[1]); // Вывод: Alice

Элементы могут быть добавлены в конец массива с помощью метода push() и удалены с помощью метода pop(). Также элементы могут быть добавлены и удалены из начала массива с помощью методов unshift() и shift().

const colors = ['red', 'green', 'blue'];
colors.push('yellow'); // Добавление элемента в конец массива
console.log(colors); // Вывод: ['red', 'green', 'blue', 'yellow']
colors.pop(); // Удаление последнего элемента массива
console.log(colors); // Вывод: ['red', 'green', 'blue']

Массивы могут быть перебраны с использованием различных методов, таких как цикл for, метод forEach(), цикл for...of и др.

// Использование цикла forfor (let i = 0; i < numbers.length; i++) {
console.log(numbers[i]);
}
// Использование метода forEach()
numbers.forEach((number) => {
console.log(number);
});
// Использование цикла for…of
for (let number of numbers) {
console.log(number);
}

JavaScript предоставляет множество встроенных методов для работы с массивами, таких как concat(), slice(), indexOf(), filter(), map() и многие другие. Эти методы предоставляют функциональность для добавления, удаления, изменения и фильтрации элементов массива.

const numbers1 = [1, 2, 3];
const numbers2 = [4, 5, 6];
const combinedNumbers = numbers1.concat(numbers2); // Объединение массивов
console.log(combinedNumbers); // Вывод: [1, 2, 3, 4, 5, 6]
const slicedNumbers = combinedNumbers.slice(2, 4); // Вырезка подмассива
console.log(slicedNumbers); // Вывод: [3, 4]
const index = combinedNumbers.indexOf(5); // Поиск индекса элемента
console.log(index); // Вывод: 4

Прототипы

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

Как работают прототипы:

Каждый объект в JavaScript имеет свой прототип. Прототип объекта – это ссылка на другой объект, известный как “родительский” объект. Когда свойство или метод не найдены в самом объекте, JavaScript автоматически обращается к его прототипу для поиска.

Если свойство или метод не найдены в прототипе объекта, JavaScript продолжает поиск в прототипе этого прототипа, и так далее, пока не будет найдено нужное свойство или метод, либо цепочка прототипов не достигнет конечного объекта null. Эта цепочка прототипов называется “цепочкой прототипов” (prototype chain).

Пример использования прототипов:

// Создание объекта с помощью литерала объекта
const animal = {
type: 'Animal',
sound: function() {
console.log('Издает звук');
}
};
// Создание нового объекта с использованием animal в качестве прототипа
const dog = Object.create(animal);
dog.type = 'Dog'; // Переопределение свойства type для объекта dog
// Вызов метода из прототипа animal
dog.sound(); // Вывод: Издает звук
// Проверка, является ли animal прототипом для dog
console.log(Object.getPrototypeOf(dog) === animal); // Вывод: true

Функции

Позволяют переиспользовать код, упрощают поддержку и читаемость.

Могу быть объявлены несколькими способами.

Function declaration

// Используем ключевое слово function
function greet(name) {
return Hi ${name}
}

Function expression

// Используем стрелочную функци
const greet = (name) => {
return Hi ${name}
}

Функции могут принимать параметры и возвращать значения. Возвращаемое значение — это результат выполнения функции. Этот результат может быть передан обратно в вызывающий код.

const summ = (x, y) => {
return x + y
}
const log = () => {
console.log(summ(1, 2))
}
log() // Результат вывода: 3

Callback functions

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

const button = document.querySelector('#myButton')
function handleClick() {
console.log('Кнопка нажата')
}
button.addEventListener('click', handleClick)

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

В чем проблема? Вложенные callback-функции могут привести к нечитаемому и трудно поддерживаемому коду, известному как “callback hell”. Этого можно избежать, используя методы, такие как Promises или async/await, которые предлагают более линейный и читаемый подход к обработке асинхронного кода.

Пример “callback hell”:

function fetchData(url, callback) {
setTimeout(() => {
const data1 = 'Данные 1';
callback(data1, (data1, callback) => {
setTimeout(() => {
const data2 = 'Данные 2';
callback(data2, (data2, callback) => {
setTimeout(() => {
const data3 = 'Данные 3';
callback(data3);
}, 1000);
});
}, 1000);
});
}, 1000);
}
fetchData('https://example.com/api', (data1, callback) => {
console.log(data1);
callback(data1, (data2, callback) => {
console.log(data2);
callback(data2, (data3) => {
console.log(data3);
});
});
});

Пример использования промисов для асинхронных запросов:

function fetchData(url) {
return new Promise((resolve, reject) => {
setTimeout(() => {
const data = 'Данные';
resolve(data);
}, 1000);
});
}
fetchData('https://example.com/api')
.then((data1) => {
console.log(data1);
return fetchData('https://example.com/api');
})
.then((data2) => {
console.log(data2);
return fetchData('https://example.com/api');
})
.then((data3) => {
console.log(data3);
})
.catch((error) => {
console.error('Произошла ошибка:', error);
});

Этот код использует промисы для выполнения асинхронных операций и избегает “callback hell”, предоставляя более линейный и читаемый подход к обработке асинхронных запросов. Каждый .then() блок представляет собой следующую операцию после успешного выполнения предыдущей. Если происходит ошибка, она обрабатывается в блоке .catch().

Прототипы и функции

В JavaScript функции также являются объектами, и у них также есть прототипы. Функции имеют свойство prototype, которое используется при создании объектов с помощью оператора new. Когда объект создается с использованием конструктора функции, прототип этой функции становится прототипом создаваемого объекта.

// Определение конструктора функции
function Person(name) {
this.name = name;
}
// Добавление метода в прототип функции Person
Person.prototype.greet = function() {
console.log(`Привет, меня зовут ${this.name}!`);
};
// Создание объекта с использованием конструктора Person
const person1 = new Person('John');
const person2 = new Person('Alice');
// Вызов метода из прототипа функции Person
person1.greet(); // Вывод: Привет, меня зовут John!
person2.greet(); // Вывод: Привет, меня зовут Alice!

Картина Три тигра

20241014_085054_2e8220.webp

Привет, мир!

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

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

Но что если инбокс не нужно разбирать? Что если инбокс нужен для сбора и каталогизации? Пусть все остаётся там же, куда положили, просто блестит по-разному.

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