Мастер Полный ES6
Объявления блочной области (let и const)
В ES6 появились ключевые слова let и const для объявления переменных. Эти объявления имеют блочную область видимости, то есть они существуют только внутри блока, в котором они объявлены, в отличие от var, область действия которой — функция.
function foo() { let x = 10; // x is block-scoped to foo const y = 20; // y is also block-scoped to foo if (true) { let x = 30; // this is a new block-scoped x, shadowing the previous one const y = 40; // this is a new block-scoped y, shadowing the previous one console.log(x, y); // output: 30, 40 } console.log(x, y); // output: 10, 20 } foo();
В этом примере ключевые слова let
и const
используются для объявления блочных переменных x
и y
. Первое объявление x
и y
находится в области видимости функции foo
, поэтому они доступны во всей функции. Второе объявление x
и y
находится в пределах блока оператора if
, поэтому они доступны только внутри этого блока.
Когда оператор console.log()
выполняется внутри блока if
, он выводит значения второго объявления x
и y
. Когда операторы console.log()
выполняются вне блока if
, они выводят значения первого объявления x
и y
.
Стоит отметить, что использование let
или const
для объявления переменной с тем же именем, что и у переменной, объявленной во внешней области видимости, создает новую переменную с тем же именем во внутреннем блоке, затеняющую внешнюю переменную. Вот почему второй оператор console.log()
выводит значение первого объявления y
, а не второго.
Стрелочные функции
Стрелочные функции обеспечивают более краткий синтаксис для написания функций. У них также есть лексическая привязка, то есть они наследуют это значение из окружающего кода.
Пример 1: Базовый синтаксис стрелочной функции
// A function that adds two numbers using arrow function syntax const add = (a, b) => a + b; console.log(add(2, 3)); // output: 5
Пример 2: Стрелочные функции с одним параметром
// A function that doubles a number using arrow function syntax const double = x => x * 2; console.log(double(3)); // output: 6
Пример 3: Стрелочные функции без параметров
// A function that returns a random number between 0 and 1 using arrow function syntax const getRandomNumber = () => Math.random(); console.log(getRandomNumber()); // output: a random number between 0 and 1
Пример 4. Стрелочные функции с несколькими операторами
// A function that checks if a number is even using arrow function syntax const isEven = x => { if (x % 2 === 0) { return true; } else { return false; } } console.log(isEven(4)); // output: true
Пример 5: Стрелочные функции с ключевым словом this
// An object with a method that uses the this keyword const person = { name: 'John', sayHi: function() { console.log('Hi, my name is ' + this.name); } } person.sayHi(); // output: Hi, my name is John // The same object with a method that uses an arrow function const person2 = { name: 'Jane', sayHi: () => { console.log('Hi, my name is ' + this.name); } } person2.sayHi(); // output: Hi, my name is undefined
В этом примере метод sayHi()
функции person2
использует функцию стрелки, что означает, что this
относится к глобальному объекту, а не к объекту, методом которого является функция. В результате выводится Hi, my name is undefined
. Это одно из различий между стрелочными функциями и обычными функциями, которые имеют собственную привязку this
.
Литералы шаблонов
Литералы шаблонов позволяют включать переменные и выражения в строки. Они используют обратные кавычки (`) вместо кавычек и допускают многострочные строки.
Пример 1. Синтаксис литерала базового шаблона
// A string with interpolated variables using template literal syntax const name = 'John'; console.log(`Hello, ${name}!`); // output: Hello, John!
Пример 2. Литералы шаблонов с выражениями
// A string with an expression using template literal syntax const x = 5; const y = 10; console.log(`The sum of ${x} and ${y} is ${x + y}.`); // output: The sum of 5 and 10 is 15.
Пример 3. Многострочные строки с использованием литералов шаблонов
// A multiline string using template literal syntax const message = `This is a multiline string using template literal syntax.`; console.log(message); // output: This is a // multiline string // using template // literal syntax.
Пример 4: Литералы шаблонов с вызовами функций
// A function that returns a string using template literal syntax function greet(name) { return `Hello, ${name}!`; } console.log(greet('John')); // output: Hello, John!
Пример 5: Литералы шаблонов с тегами
// A tagged template literal that formats a string using a custom function function formatString(strings, ...values) { let result = ''; for (let i = 0; i < strings.length; i++) { result += strings[i]; if (i < values.length) { result += values[i]; } } return result; } const x = 5; const y = 10; console.log(formatString`The sum of ${x} and ${y} is ${x + y}.`); // output: The sum of 5 and 10 is 15.
В этом примере функция formatString()
представляет собой помеченный литерал шаблона, который принимает в качестве аргументов массив строк и разброс значений. Затем он объединяет строки и значения особым образом, чтобы получить окончательную отформатированную строку. Литерал шаблона передается в качестве первого аргумента функции, а значения передаются в качестве дополнительных аргументов с использованием синтаксиса распространения.
Присваивание деструктурирования
Присваивание деструктурирования позволяет извлекать значения из массивов или объектов и назначать их переменным более кратким способом.
Пример 1: Разрушение массива
const numbers = [1, 2, 3, 4, 5]; const [first, second, ...rest] = numbers; console.log(first); // output: 1 console.log(second); // output: 2 console.log(rest); // output: [3, 4, 5]
В приведенном выше коде мы объявляем массив numbers
с некоторыми значениями. Затем мы используем деструктурирующее присваивание, чтобы присвоить первый и второй элементы массива переменным first
и second
соответственно. Мы также используем параметр rest (...rest
), чтобы присвоить оставшиеся элементы массива переменной rest
.
Пример 2: Разрушение объекта
const person = { firstName: 'John', lastName: 'Doe', age: 30, city: 'New York' }; const { firstName, lastName, age } = person; console.log(firstName); // output: John console.log(lastName); // output: Doe console.log(age); // output: 30
В приведенном выше коде мы объявляем объект person
с некоторыми свойствами. Затем мы используем деструктурирующее присваивание, чтобы присвоить свойства firstName
, lastName
и age
объекта переменным с тем же именем.
Параметры функции по умолчанию
ES6 позволяет использовать параметры функции по умолчанию, которые используются, когда в функцию не передается аргумент.
function greet(name = 'Guest') { console.log(`Hello, ${name}!`); } greet(); // output: Hello, Guest! greet('John'); // output: Hello, John!
В приведенном выше коде мы определяем функцию greet
, которая принимает параметр name
. Мы предоставляем значение по умолчанию 'Guest'
для параметра name
. Если параметр name
не указан при вызове функции, будет использоваться значение по умолчанию.
Rest-параметры
Rest-параметры позволяют передавать неопределенное количество аргументов функции в виде массива.
function sum(...numbers) { let result = 0; for (let i = 0; i < numbers.length; i++) { result += numbers[i]; } return result; } console.log(sum(1, 2, 3)); // output: 6 console.log(sum(4, 5, 6, 7)); // output: 22
В приведенном выше коде мы определяем функцию sum
, которая принимает остаточный параметр ...numbers
. Параметр rest позволяет нам представить неопределенное количество аргументов в виде массива. Внутри функции мы перебираем массив numbers
и складываем все значения, чтобы получить общую сумму.
Оператор спреда
Оператор спреда в JavaScript обозначается тремя точками ...
. Он позволяет распределять элементы итерируемого объекта (например, массива или объекта) на отдельные элементы или свойства.
Например, предположим, что у вас есть массив чисел. Если вы хотите передать эти числа как отдельные аргументы функции, вы можете использовать оператор распространения, чтобы «распределить» элементы массива по отдельным аргументам:
const numbers = [1, 2, 3]; function sum(a, b, c) { return a + b + c; } console.log(sum(...numbers)); // Output: 6
В приведенном выше коде мы используем оператор распространения для передачи массива numbers
в качестве отдельных аргументов функции sum
. Оператор расширения «распределяет» элементы массива numbers
по отдельным аргументам a
, b
и c
, чтобы функция могла вычислить их сумму.
Классы и наследование
В ES6 появился синтаксис класса для создания объектов и наследования с использованием ключевого слова extends. Классы — это способ создания объектов, которые имеют схожие свойства и методы. Они предоставляют схему создания новых объектов, которые можно повторно использовать и расширять.
Вот пример того, как определить класс в JavaScript:
class Animal { constructor(name, age) { this.name = name; this.age = age; } sayName() { console.log(`My name is ${this.name}`); } sayAge() { console.log(`I am ${this.age} years old`); } }
В приведенном выше коде мы определяем класс Animal
, который имеет метод constructor
и два дополнительных метода sayName
и sayAge
. Метод constructor
вызывается при создании нового экземпляра класса и используется для установки начальных свойств объекта.
Мы можем создать новый экземпляр класса Animal
, используя ключевое слово new
и передав необходимые аргументы методу constructor
:
const dog = new Animal('Spot', 3); dog.sayName(); // Output: "My name is Spot" dog.sayAge(); // Output: "I am 3 years old"
Наследование — это способ создания нового класса, являющегося модифицированной версией существующего класса. Это позволяет вам повторно использовать свойства и методы родительского класса и добавлять или переопределять их по мере необходимости.
Вот пример того, как определить дочерний класс, который наследуется от родительского класса в JavaScript:
class Dog extends Animal { constructor(name, age, breed) { super(name, age); this.breed = breed; } bark() { console.log('Woof!'); } sayBreed() { console.log(`I am a ${this.breed}`); } }
В приведенном выше коде мы определяем класс Dog
, который расширяет класс Animal
, используя ключевое слово extends
. Мы также определяем метод constructor
, который вызывает метод super
для передачи необходимых аргументов родительскому классу и устанавливает дополнительное свойство breed
для объекта.
Мы можем создать новый экземпляр класса Dog
так же, как и раньше:
const myDog = new Dog('Fido', 2, 'Labrador'); myDog.sayName(); // Output: "My name is Fido" myDog.sayAge(); // Output: "I am 2 years old" myDog.sayBreed(); // Output: "I am a Labrador" myDog.bark(); // Output: "Woof!"
Промисы
Промисы позволяют обрабатывать асинхронные операции и избегать ада обратных вызовов. У них есть три состояния: ожидание, выполнено и отклонено.
Вот пример использования промисов в JavaScript:
const promise = new Promise((resolve, reject) => { setTimeout(() => { const randomNum = Math.random(); if (randomNum > 0.5) { resolve(randomNum); } else { reject(new Error('Random number is less than 0.5')); } }, 1000); }); promise.then(result => { console.log(`Promise resolved with result: ${result}`); }).catch(error => { console.error(`Promise rejected with error: ${error}`); });
Здесь мы создаем новое обещание, которое имитирует асинхронную операцию с использованием setTimeout
. Если сгенерированное случайное число больше 0,5, обещание разрешается с этим значением. В противном случае он отклоняется с ошибкой.
Затем мы используем методы then
и catch
для обработки результата промиса. Метод then
вызывается, если обещание успешно разрешено, и метод catch
вызывается, если обещание отклонено.
Модули
Модули ES6 позволяют организовать код в отдельные файлы, а также экспортировать и импортировать функции между ними.
Вот пример того, как экспортировать модуль:
// module.js export function greet(name) { console.log(`Hello, ${name}!`); }
Здесь мы определяем модуль, который экспортирует одну функцию greet
. Эта функция записывает приветствие на консоль с заданным именем.
Затем мы можем импортировать этот модуль и использовать функцию greet
в другом файле:
// app.js import { greet } from './module.js'; greet('John'); // Output: "Hello, John!"
Это некоторые из основных функций, представленных в ES6. Используя эти функции, вы можете писать более лаконичный и читаемый код.
Если вы дочитали до сих пор, сделайте себе комплимент, так как не все читают от начала до конца, но вы это сделали, и у вас есть возможность оставаться впереди в жизни.