Let's have a look at the code provided in the question to see why one works and
the other doesn't.
Let's first take a look at the functioning example:
Function.prototype.defer = function (ms) {
let f = this;
return function(...args) {
setTimeout(() => f.apply(this, args), ms);
};
};
function f(a, b) {
alert(a + b);
}
f.defer(1000)(1, 2); // shows 3 after 1 second
// translates to
setTimeout(() => f.appy(this, [1, 2]), 1000);
// ^
// here `this` refers to the global object (window)
Let's have a look at the non-working example:
Function.prototype.defer = function (ms) {
return function(...args) {
setTimeout(() => this.apply(this, args), ms);
};
};
function f(a, b) {
alert(a + b);
}
f.defer(1000)(1, 2); // shows 3 after 1 second
// translates to
setTimeout(() => this.appy(this, [1, 2]), 1000);
// ^ ^
// here `this` refers to the global object (window)
Since this in the above context points to the global object (window) you could
also write this as:
setTimeout(() => window.appy(window, [1, 2]), 1000);
Since window is an object and not a function this explains the error you're
getting.
thisyou are referencing gives reference to global objectthisinside setTimeout function, but when you are storingthisin local variablefthatfis pointing to thethisof the function and not the global objectthis