116 просмотров

Современный JavaScript: ES6+ и практические примеры

Содержание

Введение в современный JavaScript

JavaScript за последние годы значительно эволюционировал. С выходом ES6 (ECMAScript 2015) и последующих версий язык получил множество новых возможностей, которые делают код более читаемым, эффективным и выразительным.

Стрелочные функции (Arrow Functions)

Стрелочные функции — один из самых популярных нововведений ES6. Они имеют более короткий синтаксис и не имеют собственного контекста this.

Синтаксис

// Старый способ
function multiply(a, b) {
    return a * b;
}

// Стрелочная функция
const multiply = (a, b) => a * b;

// Для одной строки фигурные скобки не нужны
const greet = name => `Привет, ${name}!`;

// Для нескольких строк
const process = (data) => {
    const result = data.map(item => item * 2);
    return result.filter(item => item > 10);
};

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

  • Короткие функции-преобразователи
  • Методы массивов (map, filter, reduce)
  • Обработчики событий

Важно: контекст this

// Обычная функция
const obj = {
    name: 'Объект',
    regular: function() {
        console.log(this.name); // 'Объект'
    },
    arrow: () => {
        console.log(this.name); // undefined (this из внешней области)
    }
};

Деструктуризация (Destructuring)

Деструктуризация позволяет извлекать значения из массивов и объектов в отдельные переменные.

Деструктуризация объектов

const user = {
    name: 'Иван',
    age: 30,
    email: 'ivan@example.com'
};

// Старый способ
const name = user.name;
const age = user.age;

// Деструктуризация
const { name, age } = user;

// С переименованием
const { name: userName, age: userAge } = user;

// Со значениями по умолчанию
const { name, role = 'user' } = user;

// Вложенная деструктуризация
const user = {
    name: 'Иван',
    address: {
        city: 'Москва',
        street: 'Ленина'
    }
};
const { address: { city } } = user;

Деструктуризация массивов

const numbers = [1, 2, 3, 4, 5];

// Извлечение элементов
const [first, second] = numbers;
// first = 1, second = 2

// Пропуск элементов
const [first, , third] = numbers;
// first = 1, third = 3

// Rest оператор
const [first, ...rest] = numbers;
// first = 1, rest = [2, 3, 4, 5]

// Обмен значений
let a = 1, b = 2;
[a, b] = [b, a];
// a = 2, b = 1

Шаблонные строки (Template Literals)

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

const name = 'Иван';
const age = 30;

// Старый способ
const message = 'Привет, ' + name + '! Тебе ' + age + ' лет.';

// Шаблонные строки
const message = `Привет, ${name}! Тебе ${age} лет.`;

// Многострочный текст
const html = `
    <div class="user">
        <h2>${name}</h2>
        <p>Возраст: ${age}</p>
    </div>
`;

// Выражения
const price = 100;
const discount = 20;
const total = `Итого: ${price - discount} руб.`;

Spread и Rest операторы

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

Позволяет разворачивать массивы и объекты:

// Копирование массива
const arr1 = [1, 2, 3];
const arr2 = [...arr1]; // [1, 2, 3]

// Объединение массивов
const arr3 = [...arr1, 4, 5]; // [1, 2, 3, 4, 5]

// Передача аргументов
const numbers = [1, 2, 3];
Math.max(...numbers); // 3

// Копирование объекта
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1 }; // { a: 1, b: 2 }

// Объединение объектов
const obj3 = { ...obj1, c: 3 }; // { a: 1, b: 2, c: 3 }
const obj4 = { ...obj1, a: 10 }; // { a: 10, b: 2 }

Rest оператор

Позволяет собирать оставшиеся аргументы:

function sum(first, ...rest) {
    return first + rest.reduce((a, b) => a + b, 0);
}
sum(1, 2, 3, 4); // 10

// В деструктуризации
const [first, ...others] = [1, 2, 3, 4];
// first = 1, others = [2, 3, 4]

Промисы и async/await

Промисы (Promises)

// Создание промиса
const fetchData = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const data = { id: 1, name: 'Данные' };
            resolve(data);
        }, 1000);
    });
};

// Использование
fetchData()
    .then(data => {
        console.log(data);
        return processData(data);
    })
    .then(result => {
        console.log(result);
    })
    .catch(error => {
        console.error(error);
    });

Async/Await

Более читаемый способ работы с асинхронным кодом:

// Async функция
async function getData() {
    try {
        const response = await fetch('/api/data');
        const data = await response.json();
        return data;
    } catch (error) {
        console.error('Ошибка:', error);
        throw error;
    }
}

// Использование
async function main() {
    const data = await getData();
    console.log(data);
}

main();

Методы массивов ES6+

Array.find() и Array.findIndex()

const users = [
    { id: 1, name: 'Иван' },
    { id: 2, name: 'Мария' },
    { id: 3, name: 'Петр' }
];

const user = users.find(u => u.id === 2);
// { id: 2, name: 'Мария' }

const index = users.findIndex(u => u.name === 'Мария');
// 1

Array.includes()

const numbers = [1, 2, 3, 4, 5];
numbers.includes(3); // true
numbers.includes(6); // false

Array.flat() и Array.flatMap()

const nested = [1, [2, 3], [4, [5, 6]]];
nested.flat(); // [1, 2, 3, 4, [5, 6]]
nested.flat(2); // [1, 2, 3, 4, 5, 6]

const words = ['hello world', 'foo bar'];
words.flatMap(word => word.split(' '));
// ['hello', 'world', 'foo', 'bar']

Классы ES6

class User {
    constructor(name, email) {
        this.name = name;
        this.email = email;
    }
    
    greet() {
        return `Привет, я ${this.name}`;
    }
    
    static createAdmin(name) {
        const admin = new User(name, 'admin@example.com');
        admin.role = 'admin';
        return admin;
    }
}

class Admin extends User {
    constructor(name, permissions) {
        super(name, 'admin@example.com');
        this.permissions = permissions;
    }
    
    deleteUser(userId) {
        // Логика удаления
    }
}

const user = new User('Иван', 'ivan@example.com');
const admin = Admin.createAdmin('Админ');

Модули (ES Modules)

// math.js
export const PI = 3.14159;
export function add(a, b) {
    return a + b;
}
export default function multiply(a, b) {
    return a * b;
}

// main.js
import multiply, { PI, add } from './math.js';
import * as math from './math.js';

Практические примеры

Пример 1: Обработка данных API

async function fetchUsers() {
    try {
        const response = await fetch('/api/users');
        const users = await response.json();
        
        return users
            .filter(user => user.active)
            .map(({ id, name, email }) => ({
                id,
                name,
                email: email.toLowerCase()
            }))
            .sort((a, b) => a.name.localeCompare(b.name));
    } catch (error) {
        console.error('Ошибка загрузки пользователей:', error);
        return [];
    }
}

Пример 2: Формирование объекта настроек

const defaultConfig = {
    apiUrl: 'https://api.example.com',
    timeout: 5000,
    retries: 3
};

function createConfig(userConfig) {
    return {
        ...defaultConfig,
        ...userConfig,
        headers: {
            'Content-Type': 'application/json',
            ...userConfig?.headers
        }
    };
}

Заключение

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

Начните с изучения стрелочных функций и деструктуризации — они используются чаще всего. Затем переходите к async/await для работы с асинхронным кодом. И не забывайте практиковаться на реальных проектах!

Автор статьи Evaris

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