M3 | WebDev
103 subscribers
105 photos
4 videos
14 links
Your guide to the world of programming 🌐🚀
Download Telegram
🔥 SOLID Принципы в JavaScript 🚀

SOLID — это набор из пяти принципов, которые помогают писать понятный, поддерживаемый и расширяемый код в объектно-ориентированном программировании (ООП). Давайте разберём каждый принцип с примерами на JavaScript!


1️⃣ Single Responsibility Principle (SRP) — Принцип единственной ответственности

Каждый класс должен иметь одну ответственность.

class User {
constructor(name) {
this.name = name;
}
}

class UserRepository {
save(user) {
// Сохраняет пользователя в БД
}
}

Здесь User отвечает за данные пользователя, а UserRepository — за сохранение данных. 📝


2️⃣ Open/Closed Principle (OCP) — Принцип открытости/закрытости

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

class Shape {
area() {
throw 'Метод должен быть реализован';
}
}

class Circle extends Shape {
constructor(radius) {
super();
this.radius = radius;
}

area() {
return Math.PI * this.radius * this.radius;
}
}

Вы можете добавить новый класс Square, не меняя код Circle или Shape. ⭕️🔲


3️⃣ Liskov Substitution Principle (LSP) — Принцип подстановки Барбары Лисков

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

class Rectangle {
constructor(width, height) {
this.width = width;
this.height = height;
}

area() {
return this.width * this.height;
}
}

class Square extends Rectangle {
constructor(side) {
super(side, side);
}
}

Экземпляр Square может заменить Rectangle и будет работать корректно. 🟦➡️🟥

4️⃣ Interface Segregation Principle (ISP) — Принцип разделения интерфейса

Лучше много маленьких интерфейсов, чем один большой. Пример на TS :

interface Printer {
print(doc: string): void;
}

interface Scanner {
scan(): string;
}

class MultiFunctionDevice implements Printer, Scanner {
print(doc: string) {
console.log(`Печать документа: ${doc}`);
}

scan() {
return 'Документ отсканирован';
}
}

💡 Реализуйте только необходимые интерфейсы.


5️⃣ Dependency Inversion Principle (DIP) — Принцип инверсии зависимостей

Высокоуровневые модули не зависят от низкоуровневых, оба зависят от абстракций.

class MySQLConnection {
connect() {
console.log('Подключение к MySQL');
}
}

class MongoDBConnection {
connect() {
console.log('Подключение к MongoDB');
}
}

class UserRepository {
constructor(dbConnection) {
this.dbConnection = dbConnection;
}

connect() {
this.dbConnection.connect();
}
}

const userRepository = new UserRepository(new MySQLConnection());
userRepository.connect();

Здесь UserRepository зависит от абстракции подключения к БД, а не от конкретной реализации, что упрощает замену БД. 🛠


⚙️ Применение SOLID принципов помогает создавать гибкие и поддерживаемые приложения! Используйте их, чтобы ваш код стал прочным, как камень! 💪🔥

Тэги : #javascript
💡 Всё о Web-хранилищах: `localStorage`, `sessionStorage` и `Cookies`

Веб-хранилища в JavaScript помогают сохранять данные прямо в браузере пользователя. Разберём, что из них чем отличается и где используется.

1️⃣ localStorage

- 💾 Хранение: Данные сохраняются без ограничения по времени. Даже после закрытия браузера данные останутся.
- 📦 Вместимость: Обычно около 5-10 МБ на домен.
- 📌 Применение: Подходит для хранения пользовательских настроек, корзины покупок и других данных, которые нужно сохранять между сессиями.

2️⃣ sessionStorage

- Хранение: Данные сохраняются только на время сессии. Закроете вкладку — данные исчезнут.
- 📦 Вместимость: Аналогично localStorage, но тоже около 5-10 МБ.
- 📌 Применение: Используется для временных данных, которые нужны только на время работы с одной вкладкой, например, для состояния UI или промежуточных данных форм.

3️⃣ Cookies

- 🍪 Хранение: Данные хранятся до указанного времени истечения или пока не будут удалены. Могут передаваться на сервер при каждом запросе.
- 📦 Вместимость: Обычно до 4 КБ.
- 🔒 Заголовки: Настройки безопасности и срока действия задаются с помощью заголовков Set-Cookie и атрибутов Secure, HttpOnly, SameSite.
- 📌 Применение: Идеальны для авторизации, хранения сессий пользователя и других данных, которые должны передаваться между клиентом и сервером.

🛠 Когда и что использовать?
- `localStorage` — для данных, которые нужно сохранять на долгий срок.
- `sessionStorage` — для данных, которые нужны на время сессии.
- `Cookies` — для данных, которые должны передаваться между клиентом и сервером.

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

javascript
// localStorage
// Сохранение данных
localStorage.setItem('username', 'John');

// Получение данных
const user = localStorage.getItem('username');
console.log(user); // 'John'

// Удаление данных
localStorage.removeItem('username');

// Очистка всего хранилища
localStorage.clear();

// sessionStorage
// Сохранение данных на время сессии
sessionStorage.setItem('sessionID', '12345');

// Получение данных
const session = sessionStorage.getItem('sessionID');
console.log(session); // '12345'

// Удаление данных
sessionStorage.removeItem('sessionID');

// Очистка всего сессионного хранилища
sessionStorage.clear();

// Cookies
// Создание куки
document.cookie = "theme=dark; max-age=3600; path=/";

// Получение всех куки
console.log(document.cookie); // 'theme=dark'

// Удаление куки
document.cookie = "theme=; max-age=0; path=/";

Заключение: Правильный выбор веб-хранилища помогает улучшить производительность и удобство использования веб-приложений. 🚀
🎯 Какой тип веб-хранилища передаётся на сервер с каждым HTTP-запросом? 🎯
Anonymous Quiz
8%
localStorage
0%
sessionStorage
85%
Cookies
8%
Все перечисленные
📜 Свойства объекта в JavaScript и их конфигурация

Свойства объектов в JavaScript не ограничиваются только значениями. Они обладают флагами и могут быть геттерами/сеттерами. Давайте разберемся, как это работает.

🔍 Флаги и дескрипторы свойств

Когда создается объект, его свойства имеют три базовых флага:

1. writable: Если true, значение свойства можно изменять.
2. enumerable: Если true, свойство участвует в перечислении через циклы (for...in) или методы (Object.keys).
3. configurable: Если true, свойство можно удалить, а также изменять его флаги.

Флаги задаются при помощи дескрипторов. По умолчанию все флаги имеют значение true.

🛠 Пример использования флагов

const car = { brand: "Toyota" };

Object.defineProperty(car, 'brand', {
writable: false,
enumerable: false,
configurable: false
});

// Теперь свойства "brand" не будет видно в циклах и его нельзя изменить или удалить.
console.log(car.brand); // Toyota
car.brand = "Honda"; // Ошибка: свойство недоступно для изменения


Для получения дескрипторов свойств используется Object.getOwnPropertyDescriptor:

let descriptor = Object.getOwnPropertyDescriptor(car, 'brand');
console.log(descriptor);
// Вывод: { value: 'Toyota', writable: false, enumerable: false, configurable: false }


🛠 Свойства — геттеры и сеттеры

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

- Геттер (get): возвращает значение при обращении к свойству.
- Сеттер (set): вызывается при установке значения свойства.

🛠 Пример геттеров и сеттеров

const person = {
firstName: 'Alice',
lastName: 'Johnson',

get fullName() {
return `${this.firstName} ${this.lastName}`;
},

set fullName(value) {
[this.firstName, this.lastName] = value.split(' ');
}
};

console.log(person.fullName); // Alice Johnson
person.fullName = 'John Doe';
console.log(person.firstName); // John
console.log(person.lastName); // Doe


В этом примере, при присвоении person.fullName у нас автоматически устанавливаются firstName и lastName.

📋 Практические случаи применения:

1. Контроль доступа: Изменение writable позволяет защитить важные данные от случайных изменений.
2. Настраиваемое поведение: Использование геттеров и сеттеров упрощает работу с данными, добавляя возможность валидации или форматирования.
3. Оптимизация производительности: Отключение enumerable для некоторых свойств помогает скрыть их в циклах или при копировании объектов.

📊 Сводка: В чем преимущества?

- 📌 Безопасность данных: Защита свойств от изменений или удаления.
- 📌 Гибкость: Настраиваемое поведение при чтении и записи.
- 📌 Удобство работы с объектами: Легкость реализации вычисляемых свойств и контроля за доступом.

Изучение свойств и их конфигурации поможет глубже понять JavaScript и писать более чистый и защищенный код! 🎉

Тэги : #javascript
Что будет выведено в консоль ?
Anonymous Quiz
13%
Alex
50%
Ошибка TypeError
13%
Bo
25%
undefined
Пост про связанные списки 📚

Связанный список — это абстрактная структура данных, позволяющая вставлять элементы в любую точку памяти за O(1) (константное время). Чтение элементов занимает O(n), где *n* — количество элементов в списке.

🧩 Основные компоненты связанного списка:

1. Узел (Node): Содержит значение и ссылку на следующий узел.
2. Заголовок (Head): Указывает на начало списка.
3. Хвост (Tail): Ссылка на последний узел, который ссылается на null.

Двухнаправленный связанный список:

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

📊 Сравнение массивов и связанных списков:

1. Хранение данных:

- Массив: Элементы массива хранятся в памяти последовательно, непрерывно. Это означает, что доступ к элементам массива по индексу осуществляется за константное время.

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

2. Размер и изменяемость:

- Массив: Размер массива фиксирован и определяется при создании. Изменение размера массива может потребовать перевыделения памяти и копирования элементов.

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

3. Вставка и удаление элементов:

- Массив: Вставка и удаление элементов из середины массива требует перемещения всех элементов после изменяемого, что может быть затратно по времени.

- Связанный список: Вставка и удаление элементов из середины списка требует только перенаправления указателей, что делает эти операции более эффективными.

4. Память:

- Массив: Массивы могут потреблять больше памяти, чем реально требуется, особенно если размер массива больше, чем количество используемых элементов.

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

5. Сложность операций:

- Массив: В среднем доступ к элементу массива по индексу имеет сложность O(1), а вставка и удаление элементов в середине массива имеют сложность O(n), где n - размер массива.

- Связанный список: Доступ к элементу по индексу имеет сложность O(n), а вставка и удаление элементов в середине списка имеют сложность O(1).

Пример реализации на JavaScript:

class Node {
constructor(value, next = null) {
this.value = value;
this.next = next;
}
}

class LinkedList {
constructor() {
this.head = null;
this.tail = null;
}

append(value) {
const newNode = new Node(value);

if (!this.head || !this.tail) {
this.head = newNode;
this.tail = newNode;
return this;
}

this.tail.next = newNode;
this.tail = newNode;
return this;
}

prepend(value) {
const newNode = new Node(value, this.head);
this.head = newNode;

if (!this.tail) {
this.tail = newNode;
}
return this;
}

find(value) {
if (!this.head) return null;
let current = this.head;

while (current) {
if (current.value === value) return current;
current = current.next;
}
return null;
}

insertAfter(value, prevNode) {
if (prevNode === null) return this;
const newNode = new Node(value);
newNode.next = prevNode.next;
prevNode.next = newNode;

if (newNode.next === null) this.tail = newNode;
return this;
}
}

🎯 Где используются связанные списки?

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

Тэги : #javascript #структурыданных
В какой версии ECMAScript были добавлены следующие возможности: классы, let, const, параметры по умолчанию, оператор остаточных параметров, промисы, коллекции Map и Set, и многое другое?
Anonymous Quiz
8%
A) ECMAScript 3 (ES3)
69%
B) ECMAScript 6 (ES6 / ES2015)
23%
C) ECMAScript 5 (ES5)
0%
D) ECMAScript 1 (1997)
Стек и Очередь в JavaScript 🚀

Стек (Stack) и очередь (Queue) - это основные структуры данных, которые помогают организовывать и управлять данными в программировании. Они широко используются в алгоритмах, реализации обратного пути, обработки задач, маршрутизации и многом другом. Давайте разберемся с каждой из них.


🔄 Стек (Stack)

Стек - это структура данных, работающая по принципу LIFO (Last In, First Out), что означает: последний добавленный элемент будет первым удалён.

Операции со стеком:

1. Push (добавление элемента)
2. Pop (удаление элемента)
3. Peek (просмотр верхнего элемента)
4. Проверка, пуст ли стек

Пример использования:- Реализация undo в текстовом редакторе.
- Обратный обход деревьев или графов.
Пример кода:

class Stack {   
constructor() {
this.items = [];
}

push(element) {
this.items.push(element);
}

pop() {
if (this.isEmpty()) return "Стек пуст";
return this.items.pop();
}

peek() {
return this.items[this.items.length - 1];
}

isEmpty() {
return this.items.length === 0;
}
}


🚦 Очередь (Queue)

Очередь - структура данных, работающая по принципу FIFO (First In, First Out), что означает: первый добавленный элемент будет первым удалён.

Операции с очередью:
1. Enqueue (добавление в конец)
2. Dequeue (удаление из начала)
3. Peek (просмотр первого элемента)
4. Проверка, пуста ли очередь

Пример использования:
- Обработка задач в очереди (например, очереди печати).
- Реализация кэширования с ограничением по размеру.


Пример кода:

class Queue{
constructor() {
this.items = [];
}

enqueue(element) {
this.items.push(element);
}

dequeue() {
if (this.isEmpty()) return "Очередь пуста";
return this.items.shift();
}

peek() {
return this.items[0];
}

isEmpty() {
return this.items.length === 0;
}
}


Где используются? 🤔
- Стек: используется в рекурсивных функциях, обратных обходах, реализации стековых машин, парсерах и компиляторах.
- Очередь: применяется в обработке задач в многозадачности, моделировании систем с очередями, BFS (поиск в ширину) в графах и сетях.



Выводы 📊

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


Эти структуры данных являются фундаментальными для разработки и помогают эффективно управлять данными и задачами.
Какая временная сложность операции вставки элемента в начало очереди реализованой на массиве?
Anonymous Quiz
10%
O(1)
60%
O(n)
10%
O(log n)
20%
O(n^2)
Пост про Spread и Rest операторы в JavaScript 🌟

JavaScript предоставляет два мощных оператора для работы с массивами, объектами и параметрами функций — Spread (...) и Rest (...). Несмотря на одинаковый синтаксис, они используются для разных целей.

🟢 Spread оператор (...)

Spread оператор расширяет (разворачивает) элементы массива или свойства объекта:

1. Массивы:

    const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5]; // [1, 2, 3, 4, 5]


2. Объекты:
    const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3 }; // { a: 1, b: 2, c: 3 }


3. Функции:
    const numbers = [1, 2, 3];
Math.max(...numbers); // 3

🔴 Rest оператор (...)

Rest оператор собирает оставшиеся аргументы в массив. Используется в функциях и деструктуризации:

1. Параметры функций:

    function sum(...args) {
return args.reduce((acc, val) => acc + val, 0);
}
sum(1, 2, 3); // 6


2. Деструктуризация:
    const [first, ...rest] = [1, 2, 3, 4]; // first = 1, rest = [2, 3, 4]
const { a, ...otherProps } = { a: 1, b: 2, c: 3 }; // a = 1, otherProps = { b: 2, c: 3 }


📝 Когда использовать?

- Spread: когда нужно разворачивать массивы или объекты.
- Rest: когда нужно собрать неограниченное количество аргументов или оставшиеся элементы.

Использование этих операторов помогает сделать код более гибким и удобным в работе с данными! 🎉

Тэги: #javascript