Примечание: Это статья — конспект моей лекции. В ней описываются ключевые понятия.
Типы данных
Примитивные типы данных в 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!