JavaScript匿名函數以及在循環中的匿名函數

一 歷史

JavaScript實際上是一門奇異的語言,TA的一大特性是沒有塊級做用域ajax

for(var i=0;i<10;i++){

}
console.log(i)

你們猜想下值是多少?
答案是 10, 雖然咱們在一個塊內申明瞭變量,但i倒是在全範圍內起做用的,因此就引入了匿名函數閉包

function(){
   var i=0;
   ...
}

以函數的做用域來限定變量做用域異步

二 當即執行匿名函數

固然,還當即執行的匿名函數函數

(function(){
   do sth.....
})()

第一次看到感受真tm古怪,還tm要這樣寫,太tm古怪了,咱們能夠這樣看:
定義一個虛擬變量 var foo = function(){...}
而後foo要執行,因此就線程

foo() = (function(){
       do sth.....
    })()

好了,匿名函數就當即執行了code

三 循環中的匿名函數

你們看下面一段代碼事件

function foo(){
    var arr = [];
    for(var i =0;i<5;i++){
      arr[i] = function(){
        //console.log(i) 來看看何時運行
        return i;   //定義函數時i的值並無初始化,指向函數外的i,所以,當匿名函數運行時,這個值就指向最大的i了
   }
  }
  return arr;
}

var a = foo();   //arr的賦值沒有被執行
for (var i = 0; i< 5 ;i++){
  alert(a[i]());
}

有興趣的不妨運行一下,答案是5個5,發生什麼事了呢?
咱們在對arr賦值的時候:ip

arr[i] = function(){
            return i;  
       }

函數裏面的i是沒有分配具體的值的,它指向了最外層的i,而運行時纔會賦值,因此,它就是最大的5了,再看一個例子作用域

var arr = document.getElementsByTagName("p");
            for(var i = 0; i < arr.length;i++){
                arr[i].onclick = function(){
                    alert(i);
                }
            }

這是一個DOM的onclick事件,當點擊的時想可以彈出不一樣的i值,其實是沒法實現的,因此,必須使用匿名函數的當即執行來限定做用域get

var arr = document.getElementsByTagName("p");
                for(var i = 0; i < arr.length;i++){
                    (function(j){
                        arr[j].onclick = function(){
                            alert(j);
                        }
                    })(i)
                }

四 循環中的異步函數

這樣一段代碼

for(var i=0;i<n;i++){
  ajax(i,function(....)) //這裏是一個異步調用,還有request,http等
}

這裏i會是最大值,爲什麼呢?由於這是一個異步函數,而非同步當即返回的函數,此時因爲js奇怪的單線程機制,會待同步所有結束後再運行異步的代碼,因此i始終是最大值,那麼要用什麼方法解決呢?是的,加一個閉包。

這裏留下一個問題,若是寫成這樣,你以爲能夠麼

for(var i=0;i<n;i++){
  var j={a:i}
  ajax(j.a,function(....))
}

總之,js真是一門奇異的語言

相關文章
相關標籤/搜索