鍍金池/ 問答/動(dòng)漫  網(wǎng)絡(luò)安全  HTML/ 為什么點(diǎn)擊都打印出6,而不是0,1,2,3,4,5 閉包的問題?

為什么點(diǎn)擊都打印出6,而不是0,1,2,3,4,5 閉包的問題?

<ul>
  <li>選項(xiàng)1</li>
  <li>選項(xiàng)2</li>
  <li>選項(xiàng)3</li>
  <li>選項(xiàng)4</li>
  <li>選項(xiàng)5</li>
  <li>選項(xiàng)6</li>
</ul>
  <style>
  li{
    border: 1px solid;
  }</style>
</body>
<script>
  var items = document.querySelectorAll("li");
  for(var i = 0; i<items.length;i++){
    items[i].onclick = function(){
      console.log(i)
    } 
    
  }
  
回答
編輯回答
壞脾滊

es6:

  var items = document.querySelectorAll("li");
  for(let i = 0; i<items.length;i++){
    items[i].onclick = function(){
      console.log(i)
    } 
  }

es5:

  var items = document.querySelectorAll("li");
  for(var i = 0; i<items.length;i++){
   (function(i){
        items[i].onclick = function(){
      console.log(i)
    } 
   })(i)
  }

for循環(huán)直接就運(yùn)行了跑了6次,等你點(diǎn)擊的時(shí)候i已經(jīng)等于5

2018年2月3日 20:46
編輯回答
風(fēng)清揚(yáng)

兄弟你是循環(huán)綁定事件,當(dāng)你循環(huán)結(jié)束了并未觸發(fā)任何事件,但是循環(huán)結(jié)束了,所以每個(gè)事件綁定上的都是最后一次循環(huán)的數(shù)值。事件會(huì)等到你觸發(fā)事件了再繼續(xù)執(zhí)行function內(nèi)容,而for循環(huán)可不會(huì)等你~

2018年2月4日 20:57
編輯回答
病癮

先說(shuō)你想達(dá)到預(yù)期 可以 改為let 他輸出結(jié)果為0 1 2 3 4 5

你結(jié)果是因?yàn)閖s事件處理器在線程空閑時(shí)間不會(huì)運(yùn)行,導(dǎo)致最后運(yùn)行的時(shí)候輸出的都是i最后的值

其實(shí)你這么理解 for循環(huán)是一瞬間執(zhí)行的 屬于主線程 事件處理器是在觸發(fā)的時(shí)候才會(huì)觸發(fā) 而此時(shí)觸發(fā)的的時(shí)候 i的值已經(jīng)為6(不符合循環(huán)條件時(shí)候i 為 6 ) 所以你事件觸發(fā)輸出的會(huì)全是6

2018年7月5日 11:10
編輯回答
瘋浪

因?yàn)槟泓c(diǎn)擊的時(shí)候,循環(huán)已經(jīng)結(jié)束

2018年6月12日 01:59
編輯回答
護(hù)她命

在你點(diǎn)擊的時(shí)候,已經(jīng)運(yùn)行結(jié)束了,你需要點(diǎn)擊之后將你要打印的變量保存下來(lái)(也就是先獲取相對(duì)應(yīng)的i的元素),再進(jìn)行輸出

2018年5月16日 19:57
編輯回答
朕略傻

最簡(jiǎn)單的,把 var 改成塊級(jí)作用域.
for(let i = 0; i<items.length;i++){

items[i].onclick = function(){
  console.log(i)
} 

}

2017年12月8日 11:57
編輯回答
臭榴蓮

涉及到變量提升的 點(diǎn)擊的時(shí)候已經(jīng)結(jié)束循環(huán) 使用es6的let可以解決

2017年4月8日 11:36
編輯回答
別瞎鬧

這個(gè)涉及到j(luò)s作用域以及js的運(yùn)行機(jī)制。你把這些基礎(chǔ)知識(shí)弄明白了,就不會(huì)感覺奇怪了。
在es6之前是沒有塊級(jí)作用域的概念的,只有全局作用域和函數(shù)作用域,所以這里有兩種作用域,click回調(diào)的函數(shù)作用域,全局作用域(for循環(huán)不會(huì)產(chǎn)生塊級(jí)作用域),也就是說(shuō)i屬于全局作用域。click回調(diào)里面調(diào)用了i值,但里面并沒有定義,這個(gè)變量就叫做自由變量,js對(duì)自由變量取值的邏輯是會(huì)沿著作用域鏈向上尋找,直到找到值,或找不到值為止,當(dāng)你點(diǎn)擊觸發(fā)回調(diào)的時(shí)候,函數(shù)作用域內(nèi)沒有該變量就會(huì)向上尋找,即全局作用域,此時(shí)全局作用域中的i值已經(jīng)為6了(這一點(diǎn)看明白,很重要)。所以你log數(shù)出來(lái)的每次都是6。

2018年6月2日 15:12
編輯回答
巫婆

這就是循環(huán)的,不是閉包,使用let 或者點(diǎn)擊的時(shí)候通過(guò)$(this).index()

2018年1月18日 00:52
編輯回答
枕邊人

那for循環(huán)進(jìn)行的時(shí)候,是怎么運(yùn)行的呢?
i=0時(shí),是console.log(0) 嗎 還是console.log(i)?

  1. for 循環(huán)在你一打開,或者瀏覽器一編譯的時(shí)候,已經(jīng)運(yùn)行了。由于你沒點(diǎn)擊,于是沒有觸發(fā) console.log(i);
  2. i 是全局的 i; 是 for()里面的i;所以點(diǎn)擊 item[i]會(huì)打印出循環(huán)6次結(jié)束的 i.
2017年8月21日 03:23