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真是一門奇異的語言