大家都知道javascript中的setTimeput()函数的作用,一般会用他来处理一些连续的事情,们先看一个例子:
< script >
function init()
{
setTimeout( " init2() " , 0 );
alert( " 1 " );
}
function init2()
{
alert( " 2 " );
}
< / script>
< / head>
< body onload = " init() " >
< / body>
也许很多人认为结果是:2 1, 而恰恰结果是:1 2 。这是为什么呢?明明延迟时间设置的是0,应该是立刻先执行init2()啊?我们可以这样认为,setTimeout()函数会自己重新申请一个堆栈空间,而不属于当前函数init()的堆栈空间,所以init()先入栈,alert("1")第2个入栈,当init()函数执行完后,setTimeout()才执行。
当然这里没有涉及到参数传递,再看这个例子:
< script >
var rgbcolor = new Array( 3 );
var whichtr = 0 ;
function changeColor(wh)
{
whichtr = wh;
for ( var i = 0 ;i < 3 ;i ++ )
{rgbcolor[i] = Math.ceil(Math.random() * 255 );}
trID[whichtr].style.backgroundColor = " rgb( " + rgbcolor[ 0 ] + " , " + rgbcolor[ 1 ] + " , " + rgbcolor[ 2 ] + " ) " ;
setTimeout( " changeColor( " + whichtr + " ) " , 1000 );
}
< / script>
< / head> <body>
< table border = " 1 " height = " 400 " width = " 500 " align = " center " cellspacing = " 0 " >
< tr onmousedown = " changeColor(0) " id = " trID " >< td > 0 < / td>< / tr >
< tr onmousedown = " changeColor(1) " id = " trID " >< td > 1 < / td>< / tr >
< tr onmousedown = " changeColor(2) " id = " trID " >< td > 2 < / td>< / tr >
< / table>
< / body>
当我们在表格里分别单击3个行的后,3个行的背景颜色会分别一直变颜色.这里我们就会要问:当我点击第一行后,whichtr=wh=0;当我们点击第2行后,whichtr=wh=1;此时whichter全局变量已经发生变化了,但此时第一行的颜色还在变化,点击第3行后,前面两行的颜色也一直变化,这是为什么呢?全局变量只有一个whichtr,可是他明明在我们单击后就改变了,但是3行的颜色一直变化,我们所期待的应该是每次点击后只有一行的颜色在改变。
为了看的更清楚的知道全局变量whichtr在程序运行的时变化,我们加入一句代码:document.body.innerHTML+=whichtr;
脚本代码变为:
var rgbcolor = new Array( 3 );
var whichtr = 0 ;
function changeColor(wh)
{
whichtr = wh;
for ( var i = 0 ;i < 3 ;i ++ )
{rgbcolor[i] = Math.ceil(Math.random() * 255 );}
trID[whichtr].style.backgroundColor = " rgb( " + rgbcolor[ 0 ] + " , " + rgbcolor[ 1 ] + " , " + rgbcolor[ 2 ] + " ) " ;
document.body.innerHTML += whichtr;
setTimeout( " changeColor( " + whichtr + " ) " , 1000 );
}
< / script>
此时,我在分别单击表格的三行,结果是:三上的颜色都在改边,whichtr的值是:012012012012...
这时,我们可以知道,全局变量发生了变化,而且一直在变化。
为什么?关键问题是这句代码:setTimeout("changeColor("+whichtr+")",1000);
我们可以这样来分析:
当单击第1行后,whichtr的值是0,当程序执行到setTimeout("changeColor(”+whichtr+")",1000)时,就会把0当作1000MS后执行changeColor()函数的参数.前面我们已经知道,setTimeout函数在内存中会重新申请一个堆栈来保存要运行的函数,所以,此时的whichtr=1已经被保存到另外一个内存单元中了,但这不是本来的whichtr,只能说是一个whichtr的拷贝,当1000MS时间周期到的时候,就会把whichtr==1这个拷贝当做参数传递给changeColor(),执行到whichtr=wh;时,才真正改边了whichtr这个全局变量的值.
程序中每一个onmousedown事件就会产生一个堆栈空间,每一个堆栈空间内都会有一个changeColor()函数,但是全局变量whichtr是共有的,每个堆栈内独立的运行,但这并不是多线程,javascript是单线程的,这只能算一个模拟多线程吧。
总结:
setTimeout()函数在传递参数的时候,是将一个参数的拷贝保存在setTimeout()所在的新的堆栈中,时间周期到的时候,将这个拷贝传递给调用函数。