为什么声明在函数外部的数组组件在内部不可见

时间:2013-12-13 13:53:38

标签: javascript

所以我有以下代码无法识别onclick函数中的按钮[i]变量。当然,如果我用'this'替换它,它工作正常。 (通过'works',我的意思是它按预期运行并更改页面正文的类。)我的问题是,如果在匿名函数中可以看到名为'buttons'的数组,为什么按钮[i]不可见?或者是不可见的我?我知道'this'总会在这种情况下使用,但我只是为什么按钮[i]也不起作用而感到困惑。

(function(){
     var buttons = document.getElementsByTagName("button");
     for (var i =0, len = buttons.length; i < len; i++)
     {
         buttons[i].onclick = function(){
             debugger

             var className = buttons[i].innerHTML.toLowerCase();
            // console.log(className);
             document.body.className = className;
         }
     }



}());

3 个答案:

答案 0 :(得分:1)

因为在点击时,i == buttons.lengthbuttons[i]因此未定义。有很多方法可以解决这个问题,包括bind处理程序到正确的对象,或者引入一个包含正确引用的闭包。最向后兼容的方法之一是:

for (var i =0, len = buttons.length; i < len; i++) {
    buttons[i].onclick = (function(button) {
        return function(){
            var className = button.innerHTML.toLowerCase();
            document.body.className = className;
        };
    }(buttons[i]));
 }

答案 1 :(得分:0)

这里有关闭的问题。因为循环将在某人触发click事件之前执行你的变量i = buttons.length,在这种情况下为5,因为有五个按钮。因此,当您引用buttons[i]时,您实际上引用了不存在的buttons[5]

答案 2 :(得分:0)

这与javascript闭包有关。 This article explains closures quite well

buttons [i] .onclick属性将函数引用作为参数(在您的情况下,您传入了一个匿名函数)。但是,您传入的函数与for循环的范围不同。这意味着您必须明确传递该函数内所需的任何变量。可变按钮可用,因为您已将其作为参数传递给您的anon函数。