我来尝试解释这个现象。
先说办法,就是把这句
[code="js"] alert(bb.name); [/code]
都改成
[code="js"]alert(bb.name + " - " + last.name); [/code]
再执行,你会看到
- 循环那例子连续alert了3次“2 - 2”,
- 事件那例子分别alert了“0 - 2”,“1 - 2”,“2 - 2”。
我认为原因是,[b][color=green]每次事件处理都有自己独立的context,其中保存了局部变量,比如bb。setTimeout中的function也是在这个context下执行的。[/color][/b]
- 循环例子中只有一个默认的context,循环结束后bb被改成2,所以三次都是2。
- 事件的例子中先后又有了3个独立的context,每个context里面的局部变量bb分别是0,1,2。但全局变量last还都是被改成了2。所以结果如上。
我又把第二个例子改成这样
[code="html"]
//事件demo
var i = 0;
var last = null;
document.addEventListener("click", function(event) {
var aa = {name:"aa"};
aa.name = i;
last = aa;
var bb = last;
var x = (i==0)?2000:1000;
setTimeout(function() {
alert(bb.name + " - " + last.name);
}, x);
i++;
});
[/code]
也就是让第二次点击的timeout先到期,得到的结果是“1 - 1”,“0 - 1”这样的顺序。似乎也能验证上面的论点。
所以,这个恐怕不是值传递还是引用传递的问题,而是执行context混合作用域的问题。