Javascript 变量范围的概念

Javascript concept for variable scope

我有 5 个按钮,我无法更改 DOM,不能使用 id 和 name 属性,也不能使用 innerHTML,现在我需要像单击按钮 1 时那样提供输出应该发出 "You click button # 1" 之类的警报,所有 5 个按钮都会继续。我想打印 i 的值。现在我卡住了,因为我有两个解决方案:

HTML 部分:

    //creating 5 buttons
        <button>one</button>
        <button>two</button>
        <button>three</button>
        <button>four</button>
        <button>five</button>

第一个解决方案:

            /* here I am always having you clicked element #5*/
           var nodes = document.getElementsByTagName('button');//getting    references
       var counter;
       for (var i = 0; i < nodes.length; i++) {
         nodes[i].addEventListener('click', function() {
              alert('You clicked element #' + i);
            });
        } //which is not working

第二个解决方案:

    /* here I am getting correct output*/


var nodes = document.getElementsByTagName('button');
   var counter;
    for (var i = 0; i < nodes.length; i++) {
          assignEvent(nodes[i], i);
    }

 function assignEvent(node, i){
        node.addEventListener('click', function(){
            alert('You clicked element#' + (i+1));
        });
    }//this one is working

现在我的问题是为什么解决方案 2 有效而解决方案 1 无效。请帮忙。为什么解决方案 2 正确携带了 i 的值,而解决方案 1 却没有。

在您的第一个解决方案中,当您将匿名函数添加为 addEventListener 的参数时,警报消息正在寻找 i 的最后一个值,在本例中 i=5,这会发生因为你在函数中没有局部变量,所以你唯一可能的值是全局变量。

如果你想这样做,试试这个:

        var nodes = document.getElementsByTagName('button');//getting    references

        function alertMessage(i){
            alert('You clicked element#' + (i+1));
        }

        for (i = 0; i < nodes.length; i++) {
            nodes[i].addEventListener('click', alertMessage.bind(null,i) , false);
        }

我也推荐你这个lecture

如果您不想创建额外的函数,只需将事件侦听器分配包装在您传递给的自调用匿名函数中即可 'i':

var nodes = document.getElementsByTagName('button');
var counter;
for (var i = 0; i < nodes.length; i++) {
    (function(j) {
        nodes[i].addEventListener('click', function() {
            alert('You clicked element #' + (j+1));
        });
    })(i);
}

jsfiddle 在这里:http://jsfiddle.net/vu31aa7y/

你可以这么写:

[].forEach.call(document.getElementsByTagName('button'),
    function(elt, index) {
        elt.addEventListener('click', function() {
            alert('You clicked element #' + (index + 1));
        }, false);
});