<button>一</button> <button>二</button> <button>三</button> <button>四</button> <div id="output"></div> <script> var buttons = document.querySelectorAll('button') var output = document.querySelector('#output') for (var i = 0; i < buttons.length; i++) { buttons[i].addEventListener('click', function() { output.innerText = buttons[i].innerText }) } </script>
从直观角度看 这段代码没有语义上的错误,但是当我们点击任意一个按钮时,就会报出这样的错误信息:
Uncaught TypeError: Cannot read property 'innerText' of undefined
出现这个错误的原因是因为button[i]不存在,即为undefined
每次我们点击按钮时,事件监听回调函数中得到的变量i都会等于button.length,也就是4 而button[4]恰恰不存在,所以导致错误发生
导致i得到的值都是button.length的原因是因为JavaScript中没有块儿级作用域,而使对i的变量引用(Reference)一直保持在上一层作用域(循环语句所在层)上,而当循环结束时i正好是buttons.length
做一个小改动如下:
// ... for (/* var */ let i = 0; i < buttons.length; i++) { // ... } // ...
通过 把for语句中对计数器i的定义语句从var换成let ,因为let语句会使该变量处于一个块儿级作用域中,从而让事件监听回调函数中的变量引用得到保持,
出现这个错误的原因是因为button[i] 不存在,即为undefined