Javascript是单线程语言,但它可以通过设置超时调用或间歇调用来调度代码在特定的时刻执行。JavaScript中的定时器函数包括window对象的超时调用方法setTimeout()和间歇调用方法setInterval().
定时器函数接收一个函数参数和一个延迟或间隔的毫秒数参数,返回一个调用ID。
调用定时器函数以后,定时器函数经过延迟以后将函数参数添加到任务队列中。如果队列是空的,那么函数参数立即执行;如果任务队列不为空,那么等到前面的任务执行完成之后在执行函数参数。
可以通过将调用ID作为参数传入clearTimeout() 或clearInterval()方法取消超时调用或间歇调用。
使用超时调用模拟间歇调用
在开发环境下很少使用真正的间歇调用,原因是后一个间歇调用可能会在前一个间歇调用结束之前启动,可以使用超时调用模拟间歇调用避免这一点,例如:
function doSomething(){
//代码
}
var intervalId=setInterval(doSomething,500);
使用超时调用模拟间歇调用:
function doSomething(){
//代码
setTimeout(doSomething,500);
}
var timeoutId=setTimeout(doSomething,500);
函数参数的this指向
定义一下变量和函数:
var name='Nicholas';
function Person(){
this.name='Greg';
this.sayName=function(){
console.log(this.name);
};
this.sayNameLater=function(){
setTimeout(this.sayName,500);
}
}
var person =new Person();
调用person对象 sayName()和sayNameLater()方法,结果为:
person.sayName();//'Greg'
person.sayNameLater();//"Nicholas"
可以看出,定时器函数的函数参数的内部上下文的this 指向的是window对象而不晒person对象。即:
setTimeout(this.sayName,500);
setTimeout(function(){
console.log(this.name);
});
使用闭包使this指向正确的值
修改sayNameLater()方法:
this.sayNameLater(){
var that=this;
setTimeout(function(){
that.sayName();
},500);
};
调用sayNameLater()方法的结果为:
person.sayNameLater();//'Greg'
使用bind方法
修改sayNameLater()方法:
this.sayNameLater()方法:
this.sayNameLater=function(){
setTimeout(this.sayName.bind(this),500);
};
调用sayNameLater()方法结果为:person.sayNameLater();//'Greg'
如果使用call()或apply()方法会导致函数参数立即执行而失去超时或间歇调用的效果