JavaScript Decorators & Forwarding (call, apply)

JavaScript Decorators & Forwarding (call, apply)

JavaScript Decorators & Forwarding (call, apply)

JavaScript provides decorators for modifying functions dynamically and call/apply for function forwarding. These are essential for handling function execution contexts.

🔹 call & apply – Changing Function Context

Both call and apply allow you to explicitly set the this value for a function.

Using call

function greet(greeting, punctuation) { console.log(`${greeting}, ${this.name}${punctuation}`); } const user = { name: "Alice" }; greet.call(user, "Hello", "!"); // Output: Hello, Alice!

First argument: The object to use as this.
Remaining arguments: Passed individually.

Using apply

greet.apply(user, ["Hi", "!!!"]); // Output: Hi, Alice!!!

✔ The difference: apply takes arguments as an array.

Using call & apply to Forward a Function

function sum(a, b) { return a + b; } function multiplyAndCall(func, a, b, multiplier) { let result = func.call(null, a, b); // or func.apply(null, [a, b]) return result * multiplier; } console.log(multiplyAndCall(sum, 2, 3, 4)); // Output: 20

call and apply forward function calls dynamically.

🔹 Function Borrowing

We can borrow methods from one object to another.

const person = { name: "John" }; const logger = { logName() { console.log(this.name); } }; logger.logName.call(person); // Output: John

✔ The logName method was borrowed using call.

🔹 bind – Permanent Binding

Unlike call and apply, bind returns a new function that permanently binds this.

const boundFunc = greet.bind(user, "Hey"); boundFunc("?"); // Output: Hey, Alice?

this is permanently set to user.

🔹 Decorators – Wrapping Functions

A decorator is a function that modifies another function's behavior.

Logging Decorator

function logDecorator(func) { return function(...args) { console.log(`Calling ${func.name} with arguments:`, args); return func.apply(this, args); }; } function multiply(a, b) { return a * b; } const decoratedMultiply = logDecorator(multiply); console.log(decoratedMultiply(2, 5)); // Output: Calling multiply with arguments: [2, 5] // 10

✔ The decorator logs the function call without modifying its behavior.

🔹 Throttling & Debouncing (Decorator Examples)

Throttling – Limiting Function Calls

function throttle(func, limit) { let lastCall = 0; return function(...args) { const now = Date.now(); if (now - lastCall >= limit) { lastCall = now; func.apply(this, args); } }; } const log = () => console.log("Action!"); const throttledLog = throttle(log, 2000); setInterval(throttledLog, 500); // Logs once every 2 seconds

Throttling ensures a function runs at most once per interval.

Debouncing – Delaying Execution Until User Stops

function debounce(func, delay) { let timeout; return function(...args) { clearTimeout(timeout); timeout = setTimeout(() => func.apply(this, args), delay); }; } const resizeLogger = debounce(() => console.log("Resized!"), 1000); window.addEventListener("resize", resizeLogger);

Debouncing ensures a function only runs after a delay (useful for input validation, search boxes).

🎯 Summary

call & apply – Change function this and pass arguments dynamically.
bind – Permanently set this for a function.
Decorators – Wrap functions to modify behavior (e.g., logging, throttling, debouncing).
Throttling – Limits function calls.
Debouncing – Delays execution until activity stops.

🚀 Decorators and function forwarding make JavaScript more powerful! Let me know if you need more examples. 😊

Soeng Souy

Soeng Souy

Website that learns and reads, PHP, Framework Laravel, How to and download Admin template sample source code free.

Post a Comment

CAN FEEDBACK
close