java中settimeout作用域_关于setTimeout和setInterval的this作用域问题

在一次面试中遇到了这样的一个问题:

题目如下

请问关于setTimeout中this作用域是怎么样的

其实在之前看了大量的关于this 作用域的问题,但是在回答此问题时还是回答得不够清晰,经过下来资料的查到,进行了再次学习

我们来看下面的分析

有一个函数是这样:在setTimeout中正确输出函数testThis中a的值

function testThis(){

this.a = 123;

setTimeout(function(){

console.log(this.a)

},1000)

}

test()

在浏览器中运行这个函数我们得到的结果是"undefined"

原因就是其实在setTimeout和setInterval中的this是指向Window,所以在这个时候的this.a=window.a,然而我们现在的a是指向函数,并不在window下,

我们可以看看下面的输出结果

var a = 123;

setTimeout(function(){

console.log(this.a)

},1000)

上面的输出结果就能够正确的输出a,原因是我们定义了一个全局作用域(显示全局作用域)

注:在JavaScript中以var定义的是全局作用域叫显示作用域,直接a = 123,为隐式作用域,

最大的区别就是加var 其实是定义了一个变量,而不加其实定义了一个window的属性,这个时候使用delete是可以删除不加var的,说远了更多的区别请读者自己去网上咨询,

我们继续转入正题

上面能正确的输出a但是不是改变了出题者的意愿,出题者明显是在问在函数中的使用,其实通过上面能正确输出的例子,我们已经看出了一些倪端我们只需对this进行定向保存就能解决此问题

最简单的解决方法,绑定this到一个固定变量

function test(){

this.a = 1234555;

var _this = this;

setTimeout(function(){

console.log(_this.a);

},1000)

}

test();

在看看下面的例子

function test(){

this.f = function(){

console.log(123);

setTimeout(function(){

this.f()

},1000)

}

}

var t = new test();

t.f()

按照上面的分析我们输出的肯定是只有一个“123”,setTimeout里面的f()根本就找不到

解决方法一 固定this

function test(){

this.f = function(){

var _this = this

console.log(123);

setTimeout(function(){

_this.f()

},1000)

}

}

var t = new test();

t.f()

解决方法二:利用函数的Function.prototype.bind 方法

function test(){

this.f = function(){

console.log(123);

setTimeout(this.f.bind(this),1000)

}

}

var t = new test();

t.f()

通过利用闭包call方法

function test(){

this.f = function(){

console.log(123)

setTimeout(function(a,b){

return function(){

b.call(a)

}

}(this,this.f),1000)

}

}

var t = new test();

t.f()

正确的this指向是解决此问题的关键

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值