js常见问题之为什么点击弹出的i总是最后一个
??在前端群里看見過很多人問過這個問題,今晚又有人問了這個問題,所以寫篇文章整理一下。首先看一下代碼,點擊li之后彈出當前li所對應的索引值。于是很多人刷刷刷寫出了下面的代碼。
var?aLi?=?document.getElementsByTagName('li'); for(var?i?=?0;?i?<?aLi.length;?i++){aLi[i].onclick?=?function(){alert(i);} }? 但是結果不盡人意,為了簡單,我們約定一下頁面中有2個li。點擊li之后彈出的都是2。
? 我們首先來分析一下為什么結果是1.我們可以簡單的將循環分成兩部。
??
i?=?0時,aLi[0].onclick?=?function(){alert(i)} i?=?1時,aLi[1].onclick?=?function(){alert(i)} i?=?2時,不滿足條件跳出循環.?在執行click的函數的時候,會有一個作用域鏈,這個作用域鏈是一個對象列表,這組對象定義了代碼作用域中的變量。( 關于變量對象的內容想更詳細了解的可以查看變量對象。)當我們alert(i)的時候,會去從內到外的去尋找變量i。這個時候這個函數的作用域鏈上有兩個對象,這時循環已經結束了,i此時的值為2.所以點擊任何一個li,彈出的都是2,而不是我們想要的索引值。重點在于彈出的是變量i,變量i,變量i。重要的事情說三遍。
?那么問題來了,我們要如何解決這個問題呢。我們需要做的就是在每次給aLi[i]綁定事件的時候,將這個時候i的值保存在內部的作用域中。解決方案如下。
?
var?aLi?=?document.getElementsByTagName('li');for?(var?i?=?0;?i?<?aLi.length;?i++)?{(function(i){aLi[i].onclick?=?function?()?{alert(i);};})(i) }這里涉及到一個塊級作用域的概念。在es6出來前,函數是作為創建塊級作用域的主要手段。這里我們通過在aLi[i].onclick外面套上一層函數,將i作為參數,我們重新分析一下結果。i?=?0時,(function(i){aLi[0].onclick?=?function(){alert(i);}})(0)i?=?1時,(function(i){aLi[1].onclick?=?function(){alert(i);}})(1)i?=?2時,不滿足條件跳出循環.由于多了一層自執行函數的包裹,當我們點擊li時,會有三層的作用域,從內帶外分別是:click函數內部的變量對象,自執行函數的變量對象和最外層的window對象。查找到第二層的時候,找到了i,自執行函數的i等于傳入的參數值,相對應的存下了當時i的值,所以就彈出了相應的索引值。
轉載于:https://blog.51cto.com/f2emrwu/1731520
總結
以上是生活随笔為你收集整理的js常见问题之为什么点击弹出的i总是最后一个的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jstl自定义标签接口介绍
- 下一篇: 将EXCEL中的列拼接成SQL inse