1. Function.prototype.defer = function(ms) {
    2. //'this' is the one that calls defer----user.sayHi
    3. let f = this;
    4. return function(...args) {
    5. //'this' is the one that calls the returned function
    6. setTimeout(() => f.apply(this, args), ms);
    7. }
    8. };
    9. //user.sayHi is not an entirety, regard them as separate things
    10. let user = {
    11. name: "John",
    12. sayHi() {
    13. alert(this.name);
    14. }
    15. }
    16. // user's sayHi is assigned a new function, which was returned by defer
    17. user.sayHi = user.sayHi.defer(1000);
    18. //sayHi now == return function(...args) ....
    19. //so 'this' is user
    20. user.sayHi();