function foo()
}
var f1 = foo(),
f2 = foo();
f1();
f1();
f2();
輸出:0 1 0
解析:考察點為閉包,
什麼是閉包?
當函式內部匿名函式用到函式的變數,並且匿名函式有返回值,這就形成了乙個閉包。
在乙個函式的內部定義另乙個函式,通過另乙個函式來訪問這個函式的區域性變數,這是建立閉包的最常見的方式。而閉包會常駐記憶體(增大記憶體的使用量)。
foo函式兩次分別將返回值也就是匿名函式賦值給f1 f2 ,即在堆中開闢了兩個匿名函式的空間,f1 f2分別指向乙個。因此兩者作用域互不影響。 foo 裡的匿名函式形成乙個閉包,匿名函式作用域連同返回值一起進行了賦值,也就是開闢了兩個var i =0空間。第一次呼叫,指向堆中的對應空間,輸出0,因為是i++,i++,先輸出再自家,此時i等於1,覆蓋了作用域裡的i,第二次呼叫輸出1。當呼叫f2,他指向新的空間,空間中i 等於0,因戲輸出0
閉包,在內部定義的變數不會被**,所以第二次呼叫f1()函式時,i++之後的變數可以在第二次接著使用,所有第二次呼叫f1()結果為1;
這裡需要理解閉包與傳參,內部函式會呼叫父級的引數兩次呼叫f1,此時f1的值已經是return的函式了,參見閉包,第一次搜尋父級找到零,i是被修改,放在棧中,下次再次呼叫也是直接執行return的值,而不會執行var
(1)function是引用型別:儲存在堆中,變數f1,f2是儲存在棧中;
(2)閉包:乙個函式(產生新的作用域)定義的區域性變數、子函式的作用域在函式內,
但是一旦離開了這個函式,區域性變數就無法訪問,所有通過返回子函式到乙個變數f1的方法,讓
f1指向堆中的函式作用域,這樣可以使用區域性變數i.
(3) 過程:
第一次f1() :f1=foo()中,先執行foo(): i = 0,return值返回給f1
(f1指向子函式
f1()=function(),因為子函式沒有
定義i,所以向上找到父函式定義的 i: )並執行子函式 輸出i=0,再自加 i =1(覆蓋了父函式foo 的 i值);
第二次f1() : 執行的是子函式 function(),輸出的是父函式 的 i=1,再自加 i =2;
第一次f2():同第一次f1(),不同的是 f2指向堆中乙個新的物件 function(),所有此i非彼i,輸出i=0;如果再次f2(),那麼和第二次f1(),一樣輸出i=1;
說說js閉包
js閉包涉及到作用域,js的作用域有兩種,全域性變數和區域性變數,全家變數就是在函式外宣告的,區域性變數是在函式內宣告的,函式內部可以直接讀取全域性變數 但是函式外部自然無法讀取函式內的區域性變數 函式內部宣告變數的時候,要用var不然就是個全域性變數 有時候需要得到函式內的區域性變數 濫用閉包會可...
JS閉包理解
下圖例項 body ul li 1 li li 2 li li 3 li ul body html script vara document.getelementsbytagname li for vari 0 i a.length i i 如何從外部讀取區域性變數 functionvisitinn...
JS基礎 閉包
注 自由變數是既不是在本地宣告又不作為引數傳遞的一類變數。function a return b var b a b hello closure 定義乙個函式a a中定義了函式b a中返回b 執行a 把a的返回結果賦值給變數b 執行b 閉包會在父函式外部,改變父函式內部變數的值。所以,如果你把父函式...