|
楼主 |
发表于 2008-7-18 03:48:50
|
显示全部楼层
|阅读模式
来自 内蒙古兴安盟乌兰浩特市
大家都知道javascript中的setTimeput()函数的作用,一般会用他来处理一些连续的事情.
我们先看一个例子,
Copy code
<head>
<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()才执行.
当然这里没有涉及到参数传递,再看这个例子:
Copy code
<head>
<script>
var rgbcolor=new Array(3);
var whichtr=0;
function changeColor(wh)
{
whichtr=wh;
for(var i=0;i<3;i++)
{rgbcolor=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;
脚本代码变为:
Copy code
<script>
var rgbcolor=new Array(3);
var whichtr=0;
function changeColor(wh)
{
whichtr=wh;
for(var i=0;i<3;i++)
{rgbcolor=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()所在的新的堆栈中,时间周期到的时候,将这个拷贝传递给调用函数. |
|