我们执行foo,会得到什么样的alert结果呢?100? or 0?,答案是:0。其实写过内嵌函数就知道,这里要真确的传入100,需要这样改写foo方法:
function foo() { var param = 100; var __param = param; window.setTimeout(function() { intervalRun(__param); }, 0); param = 0; }// 这样添加一个变量来存储param就可以了,这下执行foo得到的alert结果就是:100。 上面这个修正本身没有问题,可是如果我在并发执行的情况下,就可能又有新的问题。示例代码:
function doTick() { var tick = new Date().getTime(); var __tick = tick; var foo = function() { GetTick(__tick); }; window.setTimeout(foo, 3000); }
function GetTick(tick) { // to do something depend on tick parameter } 当我们在调用doTick方法时,如果以小于3000ms的频率并发,将会导致前一次的tick变量被后面执行的执行过程修改的问题,从而导致GetTick方法取到错误的tick参数。也就是说必须把doTick方法看成一个,需要"本身执行时间+3000ms"才能运行完的方法,然后再保证并行的执行doTick方法才不会出错。这样的限制条件显然是不可接受的,那么我们该怎么办呢?
其实我们只需要使用内嵌函数自身帮助我们传递参数就行了,修改后的示例如下:
function doTick() { var tick = new Date().getTime(); var foo = function() { var __tick = foo.params[0]; GetTick(__tick); }; foo.params = [tick]; window.setTimeout(foo, 0); } 由于内嵌函数构造出一个Closure Scope,它将帮组我们保存参数的Context,使我们获得真正的"异步并发调用参数传递"效果。