關於在for循環中綁定事件打印變量i是最後一次。

其實函數引用的外部變量都是最後一次的值。html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        #box{
            width:100px;
            height:100px;
            background-color:pink; } </style> <script src="index.js"></script> </head> <body> <div id="box"></div> </body> </html> ///////////////////////////////js代碼////////////////////////// window.onload = function(){ var box = document.getElementById("box"); var num = 0; function a(){ console.log(num); } box.onclick = function(){ num ++; a(); // 1,2,3,4....每次單擊都會加1,說明函數引用外部變量是引用那個變量的最後一次的值。 } }

再來看一個例子:閉包

window.onload = function(){
    var box = document.getElementById("box"); var num = 0; for(var i=0;i<10;i++){ box.onclick = function(){ console.log(i); //老是打印10  } } }

  若是你知道做用域鏈就好辦多了,在這個函數裏面的i其實引用的是最後一次i的值,爲何不是1,2,3,4...呢?由於在你for循環的時候,你並無執行這個函數,你這個函數是在你點擊的時候才執行的,當執行這個函數的時候,它發現它本身沒有這個變量i,因而向它的做用域鏈中查找這個變量i,由於當你單擊這個box的時候已經for循環完了,因此儲存在做用域鏈裏面的i的值就是10,最後就打印出來10了。函數

for(var i=0;i<10;i++){
    function a(){ console.log(i); } a(); //1,2,3,4,5.... }

爲何這樣就能夠呢?由於你在循環變量i的時候已經執行了函數a,天然變量i是什麼就打印出來什麼。性能

如今知道爲何綁定事件的時候打印出來的是最後一次的for循環的值了吧。spa

若是你知道理解這段話,我相信你知道怎麼去解決這個問題。code

  解決方法1:讓這個函數直接執行。htm

  解決方法2:將每次for循環中的變量i保存到某個地方。blog

方法1:事件

window.onload = function(){
    var box = document.getElementById("box"); var num = 0; for(var i=0;i<10;i++){ box.onclick = a(); function a(){ console.log(i); //1,2,3,4.....  } } }

  雖然這樣能夠打印出每次的變量i的值,可是咱們沒有點擊box的時候它已經執行完了,直接無視了點擊事件,也就是說這個點擊事件已經無關緊要了,因此咱們用這種方法在綁定事件中就顯得不那麼可用了,那咱們用方法2試試吧。ip

方法2:

window.onload = function(){
    var div = document.getElementsByTagName("div"); var num = 0; for(var i=0;i<div.length;i++){ (function(i){ div[i].onclick = function(){ console.log(i); } })(i) } }

  成功打印每一個i的值,原理就是經過自執行函數,而且將變量i保存到這個自執行函數的參數中。若是你不知道什麼是自執行函數能夠看初識js中的閉包這一節。

大家咱們應該選擇那種方法呢?固然看你的狀況了,若是沒有關於綁定事件的話,就是說讓這個函數直接執行的,那就用方法1,不然用方法2,另外方法2通用,可是由於裏面的i會一直保存到內存中比較消耗性能的緣由,因此在沒有必要的狀況下儘可能不要用這種方式,其實還能夠將i綁定到元素的屬性上。

相關文章
相關標籤/搜索