立即執行函式及閉包
阿新 • • 發佈:2019-01-23
1.立即執行函式
函式執行完之後,會立刻銷燬自己的AO(函式作用域物件)。
(1)(function(){}())。()是立即執行符號,裡邊可放實參只有表示式才能被執行符號執行,函式宣告是不可以的,這裡將函式宣告用算術運算子()括起來變成表示式。
所謂表示式,由運算子和運算物件組成,單獨的一個運算物件也叫表示式,如123,3<9.
(2)被執行符號執行的表示式會被忽略掉名字,因此我們一般不寫函式的名字。
2.閉包
當一個內部函式儲存到外部的時候就會形成閉包。
e:
function test() { var arr=[]; for(var i=0;i<10;i++){ arr[i] = function() { console.log(i) } } return arr } var a=test(); for(var j=0;j<a.length;j++){ a[j]() }//10,10,10,10,10,10,10,10
test()執行之後,返回陣列arr,[fun,fun,fun,fun,fun,fun,fun,fun,fun, fun]
原理:在這裡返回陣列arr裡是一些沒有執行的函式。函式執行完會銷燬自己的AO物件,但是根據執行上下文,裡邊的那個函式在定義時就繼承了test()函式的AO物件,test()函式的AO物件中有i這個變數。陣列中的函式(就是裡邊的那個函式)沒有執行自然不會去尋找i,隨著外層的迴圈,test函式中的i逐漸增加到10,因此在後來我們執行陣列的函式時,函式在自己的AO物件中找不到i,自然會去向自己繼承的那個父級AO物件中找,而此時的i已經變成了10。
解決方法:
採用立即執行函式
function test() { var arr=[]; for(var i=0;i<10;i++){ arr[i] = (function (j) { console.log(j) })(i) } return arr }原理:將i作為實參儲存到每一個函式中。