TYPESCRIPT19 октября
Декоратор в TypeScript — это функция, которая может применяться к классу, методу, свойству или параметру для изменения их поведения или добавления новых данных, свойств или методов. Декоратор предоставляет возможность модифицировать исходный элемент, к которому он применяется, без изменения его внутренней логики. Декоратор всегда реализуется как функция, хотя он может внутри использовать логику работы с классами, если это необходимо.
Представим, что декоратор в TypeScript работает как некий "контроллер" или "фильтр", который добавляет или изменяет поведение обычных объектов, методов или свойств.
Давайте рассмотрим это на житейском примере:
Исходная ситуация (без декоратора): Ты заказываешь пиццу в пиццерии. Пицца готовится по стандартному рецепту: тесто, соус, сыр, и готово.
Применение декоратора (декорированная ситуация): Представь, что шеф-повар решает улучшить пиццу с помощью "секретного ингредиента". Это его собственный фирменный штрих — например, он добавляет свежие травы или особенный соус.
Вот как это выглядит:
Применение декоратора в мире программирования:
Декоратор не изменяет саму "пиццу" (метод, класс и т.д.), но может добавить дополнительные действия — как шеф-повар, который украшает уже готовое блюдо, чтобы оно было более интересным и функциональным.
Таким образом Декоратор в TypeScript — это функция, которая применяется к классу, методу, свойству или параметру и изменяет их поведение или добавляет новые данные, свойства или методы. Его задача — влиять на элементы, к которым он применен, за счет возможности доступа к их метаданным и модификации их поведения. Важно, что декораторы не обязательно добавляют новые свойства или методы, они могут также просто изменять существующие или выполнять побочные эффекты (например, логирование).
В TypeScript декоратор всегда реализован как функция. Хотя внутри этой функции можно создавать экземпляры классов или выполнять другие действия, декораторы не реализуются непосредственно как классы. Класс может быть частью логики внутри декоратора, но сам декоратор — это всегда функция.
Логика декоратора в TypeScript заключается в том, что это специальная функция, которая получает доступ к элементам (классу, методу, свойству или параметру) и может изменить их поведение, добавляя новые свойства, методы, или изменяя существующие.
Применение декоратора: Декоратор аннотируется с помощью символа @
перед элементом, к которому применяется. Когда TypeScript компилирует код, декоратор получает доступ к метаданным этого элемента.
Функция декоратора: Декоратор — это функция, которая принимает один или несколько аргументов, в зависимости от типа элемента (класс, метод, свойство и т.д.). Эти аргументы позволяют декоратору взаимодействовать с целевым элементом.
Изменение поведения: Декоратор может изменить исходное поведение элемента несколькими способами:
Возврат измененного элемента: Декоратор может либо вернуть неизмененный элемент (например, класс), либо вернуть модифицированный элемент (например, изменить метод или конструктор).
@decorator
, он вызывает соответствующую функцию-декоратор.@log
применяется к методу add
.target
: Класс, в котором находится метод.propertyKey
: Имя метода add
.descriptor
: Описание метода, которое содержит исходную функцию.add
вызывается, будет выводиться информация об аргументах и результате.Декораторы позволяют вмешиваться в жизненный цикл классов, методов и свойств, добавляя к ним дополнительное поведение или изменяя существующее. Они работают как функции, которые принимают элемент, с которым должны работать, и могут модифицировать его по своему усмотрению, возвращая изменённую или исходную версию элемента.
Cимвол @
в TypeScript обозначает декоратор.
Когда вы видите @
, это указывает на использование декоратора для класса, метода, свойства или параметра. Этот символ вводит дополнительную функциональность, например, аннотацию или модификацию поведения объекта.
Здесь:
@logClass
— это декоратор класса. Он применяется к классу MyClass
и добавляет дополнительную логику.Декораторы являются частью стандартного синтаксиса TypeScript и используются для добавления метаданных и изменения функциональности классов и их элементов.
В фреймворке Angular декораторы также активно применяются для аннотации компонентов, сервисов и других элементов. Например, декоратор @Component
используется для описания метаданных Angular-компонента.
Декораторы в TypeScript — это специальный вид объявления, который позволяет аннотировать и модифицировать классы и их члены (методы, свойства и параметры). Декораторы работают на уровне классов, а не на уровне экземпляров объектов, и служат для того, чтобы добавлять дополнительные функциональные возможности или менять поведение классов или их частей.
Для того чтобы использовать декораторы, необходимо включить их поддержку в конфигурации TypeScript (tsconfig.json
):
Декоратор класса используется для изменения поведения самого класса.
function sealed(constructor: Function) {
Object.seal(constructor);
Object.seal(constructor.prototype);
}
@sealed
class Person {
constructor(public name: string) {}
}
let p = new Person('John');
console.log(p); // Person { name: 'John' }
|
В этом примере декоратор @sealed
"запечатывает" класс, предотвращая добавление новых свойств и методов в класс или его прототип.
@sealed
?Когда класс аннотируется декоратором @sealed
, следующие действия происходят:
Object.seal(constructor): Этот метод предотвращает добавление новых статических свойств или методов в класс Person
. Существующие свойства и методы остаются изменяемыми, но добавлять новые нельзя.
Object.seal(constructor.prototype): Этот вызов предотвращает добавление новых методов или свойств к прототипу класса, тем самым ограничивая расширение экземпляров класса. Экземпляры класса больше не могут получать новые методы или свойства через прототип.
Таким образом, этот декоратор "запечатывает" как сам класс, так и его прототип, предотвращая дальнейшие изменения.
function addTimestamp(constructor: Function) {
constructor.prototype.timestamp = new Date();
}
@addTimestamp
class User {
constructor(public name: string) {}
}
const user = new User('Alice');
console.log(user.timestamp); // Выведет текущую дату и время
|
function logCreation(constructor: Function) {
const originalConstructor = constructor;
function newConstructor(...args: any[]) {
console.log(`Создание экземпляра класса: ${originalConstructor.name}`);
return new originalConstructor(...args);
}
newConstructor.prototype = originalConstructor.prototype;
return newConstructor;
}
@logCreation
class Car {
constructor(public brand: string) {}
}
const myCar = new Car('Tesla');
// Лог:
// Создание экземпляра класса: Car
|
function validate(constructor: Function) {
return class extends constructor {
constructor(...args: any[]) {
if (args.length === 0) {
throw new Error('Нельзя создать объект без имени!');
}
super(...args);
}
};
}
@validate
class Product {
constructor(public name: string) {}
}
try {
const product = new Product('');
} catch (error) {
console.error(error.message); // Нельзя создать объект без имени!
}
|
Этот декоратор применяется к методам класса и позволяет изменять или аннотировать поведение метода.
function log(target: Object, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`Вызов метода ${propertyKey} с аргументами: ${args}`);
return originalMethod.apply(this, args);
};
return descriptor;
}
class Calculator {
@log
add(a: number, b: number): number {
return a + b;
}
}
let calc = new Calculator();
console.log(calc.add(2, 3)); // Лог вызова и результат: 5
|
В этом примере декоратор @log
оборачивает метод add
, чтобы логировать его вызовы.
Декоратор свойства позволяет изменять или аннотировать свойство класса.
function readonly(target: any, propertyKey: string) {
Object.defineProperty(target, propertyKey, {
writable: false
});
}
class Cat {
@readonly
name: string = 'Tom';
}
let cat = new Cat();
cat.name = 'Jerry'; // Ошибка: name является только для чтения
|
Здесь декоратор @readonly
делает свойство name
доступным только для чтения.
Этот декоратор применяется к параметрам методов и позволяет добавлять метаданные для параметра.
function logParameter(target: Object, propertyKey: string, parameterIndex: number) {
console.log(`Параметр в методе ${propertyKey} на позиции ${parameterIndex}`);
}
class Car {
start(@logParameter speed: number): void {
console.log(`Машина едет со скоростью ${speed}`);
}
}
let car = new Car();
car.start(100); // Лог: Параметр в методе start на позиции 0
|
В Angular декораторы широко используются для аннотации компонентов, сервисов и других сущностей.
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'My Angular App';
|
В данном примере декоратор @Component
используется для создания Angular компонента, указывая метаданные для его селектора, шаблона и стилей.
Теги: #typescript
Ваш комментарий успешно добавлен.
После проверки комментарий будет опубликован на сайте.