6.1 Основы стрелочных функций
Стрелочные функции, введенные в ECMAScript 2015 (ES6), предоставляют более компактный синтаксис для написания функций. Они обладают уникальными особенностями, такими как лексическое связывание this.
Стрелочные функции имеют более краткий синтаксис по сравнению с обычными функциями. Они определяются с помощью символа "=>" (стрелка).
Пример обычной функции и стрелочной функции:
// Обычная функция
function add(a: number, b: number): number {
return a + b;
}
// Стрелочная функция
const add = (a: number, b: number): number => a + b;
Типизация параметров и возвращаемых значений
В TypeScript вы можете явно указывать типы параметров и возвращаемых значений для стрелочных функций. Синтаксис для этого аналогичен обычным функциям.
Пример:
"use strict";
const multiply = (a, b) => {
return a * b;
};
console.log(multiply(5, 3)); // Вывод: 15
const multiply = (a: number, b: number): number => {
return a * b;
};
console.log(multiply(5, 3)); // Вывод: 15
В этом примере параметры a и b имеют тип number, и возвращаемое значение также имеет тип number.
Контекст this в стрелочных функциях
Одной из ключевых особенностей стрелочных функций является их лексическое связывание this. Это означает, что this внутри стрелочной функции всегда ссылается на значение this в окружающем контексте.
Пример:
"use strict";
class Counter {
constructor() {
this.count = 0;
this.increment = () => {
this.count++;
};
}
}
const counter = new Counter();
counter.increment();
console.log(counter.count); // Вывод: 1
class Counter {
count: number = 0;
increment = (): void => {
this.count++;
};
}
const counter = new Counter();
counter.increment();
console.log(counter.count); // Вывод: 1
В этом примере стрелочная функция increment сохраняет значение this, которое ссылается на экземпляр класса Counter, даже если функция вызывается вне контекста класса.
6.2 Стрелочные функции в объектах
Стрелочные функции могут быть свойствами объектов. В таких случаях типизация параметров и возвращаемых значений также важна.
Пример:
"use strict";
const calculator = {
add: (a, b) => a + b,
subtract: (a, b) => a - b
};
console.log(calculator.add(10, 5)); // Вывод: 15
console.log(calculator.subtract(10, 5)); // Вывод: 5
interface MathOperations {
add: (a: number, b: number) => number;
subtract: (a: number, b: number) => number;
}
const calculator: MathOperations = {
add: (a, b) => a + b,
subtract: (a, b) => a - b
};
console.log(calculator.add(10, 5)); // Вывод: 15
console.log(calculator.subtract(10, 5)); // Вывод: 5
Здесь интерфейс MathOperations описывает объект с двумя стрелочными функциями: add и subtract. Объект calculator реализует этот интерфейс.
Стрелочные функции и массивы
Стрелочные функции часто используются с методами массивов, такими как map, filter и reduce.
Пример использования map:
"use strict";
const numbers = [1, 2, 3, 4, 5];
const squares = numbers.map(num => num * num);
console.log(squares); // Вывод: [1, 4, 9, 16, 25]
const numbers: number[] = [1, 2, 3, 4, 5];
const squares: number[] = numbers.map(num => num * num);
console.log(squares); // Вывод: [1, 4, 9, 16, 25]
В этом примере стрелочная функция используется для возведения каждого элемента массива numbers в квадрат.
Пример использования filter:
"use strict";
const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.filter(num => num % 2 === 0);
console.log(evenNumbers); // Вывод: [2, 4]
const numbers: number[] = [1, 2, 3, 4, 5];
const evenNumbers: number[] = numbers.filter(num => num % 2 === 0);
console.log(evenNumbers); // Вывод: [2, 4]
В этом примере стрелочная функция используется для фильтрации четных чисел из массива numbers.
Пример использования reduce:
"use strict";
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((total, num) => total + num, 0);
console.log(sum); // Вывод: 15
const numbers: number[] = [1, 2, 3, 4, 5];
const sum: number = numbers.reduce((total, num) => total + num, 0);
console.log(sum); // Вывод: 15
В этом примере стрелочная функция используется для вычисления суммы всех элементов массива numbers.
Стрелочные функции в функциональном программировании
Стрелочные функции являются важной частью функционального программирования. Они позволяют легко создавать компактные и понятные функции высшего порядка.
Пример:
"use strict";
const add = (a) => {
return (b) => a + b;
};
const addFive = add(5);
console.log(addFive(10)); // Вывод: 15
const add = (a: number): (b: number) => number => {
return (b: number): number => a + b;
};
const addFive = add(5);
console.log(addFive(10)); // Вывод: 15
В этом примере функция add возвращает другую функцию, которая добавляет переданное значение к a. Это пример замыкания, где внутренняя функция имеет доступ к переменным внешней функции.
6.3 Примеры с более сложной типизацией
TypeScript позволяет создавать более сложные типы для стрелочных функций, используя интерфейсы и типы.
Пример с интерфейсом:
interface Transform {
(value: string): string;
}
const toUpperCase: Transform = value => value.toUpperCase();
const toLowerCase: Transform = value => value.toLowerCase();
console.log(toUpperCase('Hello')); // Вывод: HELLO
console.log(toLowerCase('WORLD')); // Вывод: world
В этом примере интерфейс Transform описывает функцию, которая принимает строку и возвращает строку. Стрелочные функции toUpperCase и toLowerCase реализуют этот интерфейс.
Пример с дженериками:
"use strict";
function map(array, func) {
return array.map(func);
}
const numbers = [1, 2, 3];
const strings = map(numbers, num => num.toString());
console.log(strings); // Вывод: ['1', '2', '3']
function map<T, U>(array: T[], func: (item: T) => U): U[] {
return array.map(func);
}
const numbers: number[] = [1, 2, 3];
const strings: string[] = map(numbers, num => num.toString());
console.log(strings); // Вывод: ['1', '2', '3']
В этом примере функция map использует дженерики (generics) для работы с массивами любого типа. Стрелочная функция, переданная в map, преобразует числа в строки.
Пример использования стрелочных функций в классах
Стрелочные функции часто используются в классах для обеспечения корректного связывания this.
Пример:
"use strict";
class Timer {
constructor() {
this.seconds = 0;
}
start() {
setInterval(() => {
this.seconds++;
console.log(this.seconds);
}, 1000);
}
}
const timer = new Timer();
timer.start();
class Timer {
seconds: number = 0;
start() {
setInterval(() => {
this.seconds++;
console.log(this.seconds);
}, 1000);
}
}
const timer = new Timer();
timer.start();
В этом примере стрелочная функция, переданная в setInterval, сохраняет значение this, которое ссылается на экземпляр класса Timer.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ