1.首先要清楚,JavaScript是单线程语言,一段时间内只能执行一段代码。因此就有一个JavaScript的任务队列来控制代码的执行顺序。window对象的属性setTimeout()的第二个参数就是告诉JavaScript再过多长时间将当前任务添加到队列中。如果队列是空的,那么添加的代码会立即执行;如果队列不是空的,那么先等到前面的代码执行完后再执行。间歇调用setInterval()与超时调用相似,只不过是重复调用。
setTimeout(function(){ alert("Hello"); },1000);
//setTimeout()与setInterval()的第一个参数可以是函数,也可以使字符串,但是不建议使用字符串,因为代码包裹在字符串中需要二次解析会导致性能问题。还会引起作用域问题
var name="liu";
function sayName(){
var name="liuliu";
setTimeout("alert(name)",1000); //字符串形式 liu
}
sayName();
//////////////////////////////////////////////////
var name="liu";
function sayName(){
var name="liuliu";
setTimeout(function(){
alert(name);
},1000); //函数形式 liuliu
}
sayName();
2.超时调用和间歇调用都返回一个标识符,可以用于取消调用,clearTimeout()与clearInterval()。一般只有间歇调用需要取消调用操作,不然会重复下去。在实际中一般使用超时调用模拟间歇调用,因为间歇调用可能在前一个间歇调用结束之前调用。
//间歇调用
var num=0, max=5, intervalId=null; function incrementNumber(){ num++; if(num==max){ clearInterval(intervalId); //当num=max时取消间歇调用 alert(num); } } setInterval(incrementNumber,1000); //间歇调用
//用超时调用模拟间歇调用
var num=0,
max=5;
function incrementNumber(){
num++;
if(num<max){
setTimeout(arguments.callee,1000); //回调函数,且解除函数与函数名的耦合关系
}else{
alert(num);
}
}
setTimeout(incrementNumber,1000); //超时调用
3.超时调用的代码都是在全局作用域中执行的,因此函数的this值在非严格模式下指向window对象,在严格模式下是undefined。
var name="liu"; var o={ name:"liuliu", sayName:function(){ alert(this.name); //liuliu } }; o.sayName(); //超时调用的this值 var name="liu"; var o={ name:"liuliu", sayName:function(){ setTimeout(function(){ //超时调用 alert(this.name); //liu },1000); } }; o.sayName();
4.调用的两种方式:
function sayName(){ alert("liu"); } function test(){ function sayName(){ alert("liuliu"); } setTimeout(sayName,1000); //liuliu setTimeout("sayName()",1000); //liu } test();
//////////////////////////////////////////////////// function sayName(){ alert("liu"); } function test(){ /* function sayName(){ alert("liuliu"); }*/ setTimeout(sayName,1000); //liu setTimeout("sayName()",1000); //liu } test(); //////////////////////////////////////////////////// /* function sayName(){ alert("liu"); }*/ function test(){ function sayName(){ alert("liuliu"); } setTimeout(sayName,1000); //liu setTimeout("sayName()",1000); //显示sayName未定义 } test(); //////////////////////////////////////////////////// (function(){ //添加了个块级作用域 function sayName(){ alert("liu"); } function test(){ function sayName(){ alert("liuliu"); } setTimeout(sayName,1000); //liuliu setTimeout("sayName()",1000); //显示sayName未定义 } test(); })();
setTimeout("sayName()",1000)这种形式,只能调用全局作用域中的函数,我不建议使用这种方式。setTimeout(sayName,1000)遵守一般的作用域访问规则。