Function.prototype.defer = function(ms) {
//'this' is the one that calls defer----user.sayHi
let f = this;
return function(...args) {
//'this' is the one that calls the returned function
setTimeout(() => f.apply(this, args), ms);
}
};
//user.sayHi is not an entirety, regard them as separate things
let user = {
name: "John",
sayHi() {
alert(this.name);
}
}
// user's sayHi is assigned a new function, which was returned by defer
user.sayHi = user.sayHi.defer(1000);
//sayHi now == return function(...args) ....
//so 'this' is user
user.sayHi();