Javascript 作为参数的匿名函数的作用域

Javascript 作为参数的匿名函数的作用域,javascript,html,css,this,anonymous-function,Javascript,Html,Css,This,Anonymous Function,我正在开发一个非常简单的应用程序。当用户将鼠标悬停在任何列表项(li)上时,文本颜色将变为绿色,当鼠标离开时,文本颜色将变为黑色 为什么我们不能在匿名函数的下面一段代码中使用lis[i]而不是this关键字 var lis = document.querySelectorAll('li'); var i = 0; for(; i < lis.length; i++){ lis[i].addEventListener('mouseover', function(){ th

我正在开发一个非常简单的应用程序。当用户将鼠标悬停在任何列表项(
li
)上时,文本颜色将变为绿色,当鼠标离开时,文本颜色将变为黑色

为什么我们不能在匿名函数的下面一段代码中使用
lis[i]
而不是
this
关键字

var lis = document.querySelectorAll('li');
var i = 0;
for(; i < lis.length; i++){

    lis[i].addEventListener('mouseover', function(){

    this.style.color = 'green';

    });
    lis[i].addEventListener('mouseout', function(){

    this.style.color ="black";  
    });
};
var lis=document.querySelectorAll('li');
var i=0;
对于(;i
调用函数时,循环将完成。只有一个
i
变量,函数总是看到它的当前值。因此,如果从函数内部使用
i
,您将看到它的值为
lis.length

这是有办法的。如果您可以使用ES2015(可能通过transpiler),那么您可以编写:

const lis = document.querySelectorAll('li');
for(let i = 0; i < lis.length; i++){

    lis[i].addEventListener('mouseover', () => lis[i].style.color = 'green');
    lis[i].addEventListener('mouseout', () => lis[i].style.color ="black");
};

(这是babel根据我上面给出的ES2015示例自动生成的代码)

当执行回调函数时,
I
变量将由于循环而具有
lis.length
,导致
lis[I]
的值
未定义

您可以使用
forEach
函数

var lis=document.querySelectorAll('li');
lis.forEach(功能(li){
li.addEventListener('mouseover',函数(){
li.style.color='绿色';
});
li.addEventListener('mouseout',函数(){
li.style.color=“黑色”;
});
});
  • 第一李
  • 二里
您可以使用“e.srcElement”获得如下当前目标

let lis=document.querySelectorAll('li');
for(设i=0;i
  • 第一李
  • 二里

实际上,
i
仍将被定义,但停留在for循环的最后一个值上(在本例中为lis.length,使
lis[i]
未定义)。这是由于Javascript闭包造成的。请看@Duncan的答案。@MichaelYang感谢您指出,我更关注解决方案,而不是问题的根源。当然,您的解决方案非常好!我只想指出:-)他们可以,但这与他们提出的问题无关
var lis = document.querySelectorAll('li');

var _loop = function _loop(i) {

    lis[i].addEventListener('mouseover', function () {
        return lis[i].style.color = 'green';
    });
    lis[i].addEventListener('mouseout', function () {
        return lis[i].style.color = "black";
    });
};

for (var i = 0; i < lis.length; i++) {
    _loop(i);
}