Function Methods Polyfill
Call Polyfill
const person = {
sayFullName: function (state, city) {
return `${this.fName} ${this.lName} lives in ${city} ${state}`;
},
};
const john = {
fName: "John",
lName: "Clark",
};
Function.prototype.myCall = function (ctx, ...args) {
if (typeof this !== "function") throw new Error("Not callable");
ctx = ctx || globalThis;
const id = Symbol();
ctx[id] = this;
const result = ctx[id](...args);
delete ctx[id];
return result;
};
console.log(person.sayFullName.myCall(john, "Uttar Pradesh", "Lucknow"));
Apply Polyfill
const person = {
sayFullName: function (state, city) {
return `${this.fName} ${this.lName} lives in ${city} ${state}`;
},
};
const john = {
fName: "John",
lName: "Clark",
};
Function.prototype.myApply = function (ctx, args) {
if (typeof this !== "function") throw new Error("Not callable");
ctx = ctx || globalThis;
const id = Symbol();
ctx[id] = this;
const result = ctx[id](...(args || []));
delete ctx[id];
return result;
};
console.log(person.sayFullName.myApply(john, ["Uttar Pradesh", "Lucknow"]));
Bind Polyfill
const person = {
sayFullName: function (state, city) {
return `${this.fName} ${this.lName} lives in ${city} ${state}`;
},
};
const john = {
fName: "John",
lName: "Clark",
};
Function.prototype.myBind = function (ctx, ...args) {
if (typeof this !== "function") throw new Error("Not callable");
const self = this;
return function (...newArgs) {
return self.apply(ctx, [...args, ...newArgs]);
};
};
console.log(person.sayFullName.bind(john, "Uttar Pradesh")("Lucknow"));
Soft Binding
const softBind = (obj, fn) => {
return function (...args) {
const globalCtx = typeof window !== 'undefined' ? window : globalThis
return fn.apply(
(!this || this === globalCtx) ? obj : this, args
)
}
}
const person = {
empName: 'Alex',
age: 28,
isDisabled: false,
greet: function () {
console.log(`Hi, my name is ${this.empName}.`);
}
}
const bound = softBind(person, person.greet)
bound()
bound.call({ empName: 'Robert' })
Debounce
const debounce = (fn, wait) => {
let timer;
return (...args) => {
if (timer) clearTimeout(timer)
timer = setTimeout(() => fn(...args), wait)
}
}
const callJohn = (name) => {
console.log(`Hi ${name}`);
}
const fn = debounce(() => callJohn('Johnyy'), 2000)
fn()
Throttle
const throttle = (fn, wait) => {
let last = 0
return (...args) => {
const now = Date.now()
if (now - last >= wait) {
last = now
fn(...args)
}
}
}
//OR
const throttle = (fn, wait) => {
let isThrottled = false;
return (...args) => {
if (!isThrottled) {
fn(...args);
isThrottled = true;
setTimeout(() => {
isThrottled = false;
}, wait);
}
};
};
const callJohn = (name) => {
console.log(`Hi ${name}`);
}
const fn = throttle(() => callJohn('Braddd'), 2000)
setTimeout(() => fn(), 1000) //ignored 1000<2000
setTimeout(() => fn(), 1100) //ignored 1000<2000
setTimeout(() => fn(), 1200) //ignored 1000<2000
setTimeout(() => fn(), 2500) //Hi Braddd