for(var i=0;i<as.length;i++){ as[i].onmouseover=function(){ this.style.background='grey';//这里用as[i]代替this就不会改变背景色 } as[i].onmouseout=function(){ this.style.background='none'; } as[i].onclick=function(){ title.innerHTML=this.innerHTML; } }
在这段程序里,既然this指当前事件的对像as[i],为什么不能用as[i].style.background='grey';来取代this呢?
问题在于:对于变量的作用域混淆,原因:当 onmouseover 事件执行函数时,它不认识 as[i] 是什么东西;
首先明确一点:this是指对当前对象的引用,这是JS语法规定。
从你的代码可以看出,this是指 li 对象(假定你的 as[i] 是一个 li 对象),而 onmouseover 调用的是匿名方法,即onmouseover=function(){...},这是简写,语法规定可以这么写:
as[i].onmouseover=function(){ this.style.background='grey';//这里用as[i]代替this就不会改变背景色 }
现在,我们把它的具体引用写出来,假定这个方法被声明为 changBg(),那么就是:
as[i].onmouseover=changeBg(); function changeBg(){ this.style.background='grey';//this是指对当前对象的引用,这是JS语法规定。 } //当我们 this 改为 as[i] 的时候, function changeBg(){ as[i].style.background='grey';// as[i] 在这个方法内是什么?as[i] 既不是全局变量,也不是方法内的局部变量,所以它不会被识别出来,从而导致这条代码无法实现功能 }
当然,我也是初学者,以上是我的理解,不敢保证100%正确,希望能帮到你。: )
这与闭包有关,i是绑定在其作用域所在的函数,在循环的额每次迭代中,循环体都会为嵌套函数(这里是mouseover的事件处理程序)创建一个闭包,而闭包存储的是变量i的引用,由于每次迭代后,i的值均在变化,因此内部函数最终得到的就是i最后的值(as.length)。
因为这个不是按下键盘再进行循环的,是先进行循环对所有对象添加了事件然后你再进行操作调用这个事件,当你按下事件的时候循环中的i值已经大于as.length了