JavaScript函数延迟包装器问题:解决this上下文丢失问题
解决setTimeout丢失函数上下文的问题
嘿,这个问题我太熟悉了!咱们先搞明白为啥调用defer的时候会输出undefined:当你把函数直接传给setTimeout时,它执行的时候默认的this会指向全局对象(浏览器里是window,Node.js里是global),完全跟原来的obj1/obj2没关系了,自然拿不到someProp。
下面给你几种靠谱的解决方案,随便选一种都能搞定:
方案1:用箭头函数继承上下文
箭头函数不会创建自己的this,它会继承外层作用域的this——也就是defer方法被调用时的this(也就是obj1或者obj2)。修改后的代码如下:
function someFunc() { console.log(this.someProp); } var obj1 = { someProp: 1, method1: someFunc, }; var obj2 = { someProp: 2, method2: someFunc, }; Function.prototype.defer = function(ms) { setTimeout(() => { this(); // 这里的this就是原来的obj1/obj2 }, ms); }; obj1.method1(); // 1 obj2.method2(); // 2 obj1.method1.defer(1000); // 1 after 1 sec obj2.method2.defer(1000); // 2 after 1 sec
方案2:用bind绑定固定上下文
bind方法会返回一个新函数,这个函数的this会被永久绑定到你传入的对象上。这里我们把当前的this(也就是obj1/obj2)绑定给原函数:
Function.prototype.defer = function(ms) { setTimeout(this.bind(this), ms); };
方案3:手动保存上下文到变量
这是ES6之前常用的方式,把当前的this存到一个变量里,在setTimeout的回调里调用这个变量指向的函数:
Function.prototype.defer = function(ms) { const context = this; setTimeout(function() { context(); // 这里的context就是原来的obj1/obj2 }, ms); };
这三种方案都能完美保留函数的上下文,你可以根据自己的代码风格选择~
内容的提问来源于stack exchange,提问作者sandbox992
相关产品推荐
相关产品推荐

