Loading article...
The apply method in JavaScript is similar to call, except that it takes arguments as an array.
Function.prototype.applyNative behavior:
function greet(age, city) { console.log(`Hello, my name is ${this.name}, I am ${age} years old, and I live in ${city}.`); } const person = { name: "Alice" }; greet.apply(person, [25, "New York"]);
π Difference from call :
call(context, arg1, arg2, arg3, ...) β Arguments are passed individually.apply(context, [arg1, arg2, arg3, ...]) β Arguments are passed as an array.applyWe need to:
thisArg (context).Function.prototype.myApply = function (context, args) { if (typeof this !== "function") { throw new TypeError("myApply can only be used on functions"); } context = context || globalThis; // Default to global (window in browser, global in Node.js) const fnKey = Symbol(); // Unique key to avoid property collisions context[fnKey] = this; // Assign function to context const result = context[fnKey](...(args || [])); // Invoke function with spread operator delete context[fnKey]; // Cleanup return result; };
function greet(age, city) { console.log(`Hello, my name is ${this.name}, I am ${age} years old, and I live in ${city}.`); } const person = { name: "Bob" }; greet.myApply(person, [30, "Los Angeles"]); // Output: Hello, my name is Bob, I am 30 years old, and I live in Los Angeles.
Let's break it down for:
greet.myApply(person, [30, "Los Angeles"]);
myApplygreet.myApply(person, [30, "Los Angeles"]);
this inside myApply refers to greet.context = person ({ name: "Bob" }).args = [30, "Los Angeles"].Inside myApply:
Function.prototype.myApply = function (context, args) { if (typeof this !== "function") { throw new TypeError("myApply can only be used on functions"); }
β
this is greet (a function), so no error.
contextcontext = context || globalThis;
context = person.const fnKey = Symbol(); context[fnKey] = this;
person:
{ name: "Bob", [Symbol(fnKey)]: function greet(age, city) { ... } }
const result = context[fnKey](...(args || []));
person ;
this is now person, it prints:
Hello, my name is Bob, I am 30 years old, and I live in Los Angeles.
delete context[fnKey];
person, restoring it to:
{ name: "Bob" }
| Step | Action |
|---|---|
| 1οΈβ£ | greet.myApply(person, [30, "Los Angeles"])is called |
| 2οΈβ£ | context = person |
| 3οΈβ£ | Symbol(fnKey)is created and assigned to person[Symbol(fnKey)] = greet |
| 4οΈβ£ | person is invoked, printing "Hello, my name is Bob, I am 30 years old, and I live in Los Angeles." |
| 5οΈβ£ | Temporary function property is deleted |
β
Works just like the native apply method!
Test your understanding with 3 quick questions