Suggest an editImprove this articleRefine the answer for “Decorator function”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)A **decorator function** is a special kind of **wrapper function** that **modifies the behavior of another function** **without changing its source code**. **Key point:** a decorator is a function that takes another function and returns a new one, with the same interface but extended behavior.Shown above the full answer for quick recall.Answer (EN)ImageA **decorator function** is a special kind of **wrapper function** that **modifies the behavior of another function** **without changing its source code**. This is a powerful pattern often found in functional programming, Python, and modern JS frameworks (for example, NestJS, React decorators, MobX, etc.). Let's look at it in detail. --- ## Definition > A **decorator function** is **a function that takes another function and returns a new one**, with the same interface but **extended behavior**. Essentially, this is a "wrapper with intent" - it **decorates** (embellishes, adds capabilities to) the source function without changing it directly. --- ## Basic example ```javascript function decorator(fn) { return function(...args) { console.log('Before calling the function'); const result = fn(...args); console.log('After calling the function'); return result; }; } function sayHello(name) { console.log(`Hello, ${name}!`); } const decorated = decorator(sayHello); decorated('Bohdan'); ``` Output: ```javascript Before calling the function Hello, Bohdan! After calling the function ``` Here `decorator` added "behavior before and after" without changing `sayHello` itself. --- ## Example 2 - a decorator for measuring execution time ```javascript function measureTime(fn) { return function(...args) { const start = performance.now(); const result = fn(...args); const end = performance.now(); console.log(`Execution time: ${(end - start).toFixed(2)}ms`); return result; }; } function heavyCalc(n) { for (let i = 0; i < n; i++) {} } const timedCalc = measureTime(heavyCalc); timedCalc(1e7); ``` --- ## Example 3 - a decorator for try/catch ```javascript function safe(fn) { return function(...args) { try { return fn(...args); } catch (err) { console.error('Error:', err.message); } }; } function risky() { throw new Error('Something went wrong'); } const safeRisky = safe(risky); safeRisky(); // Error: Something went wrong ``` Such a decorator is often used to **automatically catch errors** across dozens of functions without duplicating try/catch. --- ## Example 4 - decorators in "composition" style Several decorators can be combined: ```javascript const log = fn => (...args) => { console.log(`Calling ${fn.name} with arguments:`, args); return fn(...args); }; const time = fn => (...args) => { const start = performance.now(); const result = fn(...args); console.log(`${fn.name} executed in ${performance.now() - start}ms`); return result; }; function sum(a, b) { return a + b; } const decoratedSum = log(time(sum)); decoratedSum(5, 7); ``` Decorators can be **combined**, like filters: each adds a "layer" of functionality. --- ## Example 5 - class and method decorators (ES7 syntax) JS supports **decorators at the class level** (in NestJS, Angular, MobX, etc.): ```javascript function Log(target, property, descriptor) { const original = descriptor.value; descriptor.value = function(...args) { console.log(`Calling ${property} with:`, args); return original.apply(this, args); }; return descriptor; } class User { @Log sayHello(name) { console.log(`Hello, ${name}!`); } } new User().sayHello('Bohdan'); ``` Here `@Log` automatically "wraps" the `sayHello` method. This is syntactic sugar for: ```javascript User.prototype.sayHello = Log(User.prototype, 'sayHello', descriptor).value; ``` --- ## Decorators != just wrappers | Difference | Wrapper | Decorator | |---|---|---| | Purpose | Add logic around a function | Change or extend a function's behavior | | Returns | Usually a new function | Also a new one, but with the same interface | | Often used | For protection (try/catch), logging, throttling | For annotations, DI, validation, caching | | Level | Any function | Often methods or classes | | In JS (ES) | No special syntax before ES2022 | Has `@decorator` syntax | --- ## SUMMARY | Property | Description | |---|---| | What it is | A function that takes another function and returns a modified one | | Purpose | Add functionality without changing the source code | | Type | Higher-order function | | Typical examples | Logging, caching, metrics, security, annotations | | Support in ES | ES7+ (via `@decorator` syntax) |For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.