關於js閉包的誤區

2022-05-06 14:21:09 字數 1439 閱讀 6480

一直以為js的閉包只是內部函式儲存了乙份外部函式的變數值副本,但是以下**打破了我的認識:

function createfunctions()

} return result;

}var funcs = createfunctions();

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

執行結果是10個10 而不是0-9

看了js高階程式設計7.2.1之後才明白 變數i並不是存在於匿名函式的區域性變數表,而是儲存在createfunctions的活動物件表(儲存引數和區域性變數)中。並且在建立函式的定義過程中匿名函式只是被定義而沒有被執行。直到後面輸出的迴圈被定義的匿名函式們才得以執行,而這時候它們的活動物件表裡並不存在i,然後它們就會從作用域鏈向上查詢createfunctions的活動物件表中的i。這時i的值已經是10,因此它們的執行結果全是10。

以下**在閉包外部再加入了乙個含引數的閉包,並且在定義之後呼叫,傳遞進去當前的i。這時這層新增的閉包活動物件表中含有引數num會儲存i的當前值。這樣結果就是0-9了:

1

function

createfunctions()212

}(i);13}

14return

result;15}

1617

var funcs =createfunctions();

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

19

閉包的活動物件表中並不會包含this,this是當前執行上下文中的概念,會隨著呼叫環境而變化。

1 name = "global name"

2var obj =9}

10}11console.log(obj.func()());

1213

var obj2 =21}

22}23console.log(obj2.func()());

2425

var obj3 =31}

32console.log(obj3.func());

33console.log((obj3.func)());

34 console.log((obj3.func = obj3.func)());

輸出結果:

global name

object name

object name

object name

global name

第乙個輸出 因為this並不在活動物件表裡,閉包在呼叫的地方才獲得當前的this,也就是全域性物件

第二個輸出 因為閉包定義之前取了this存到外層函式的that變數,用that就可以得到自定義物件

第3,4個輸出 沒有閉包 直接輸出this

第五個輸出 因為賦值表示式取結果的操作把當前的上下文變成了全域性的,可以當做賦值操作不屬於任何物件因此得到的是全域性物件

關於js閉包的誤區

一直以為js的閉包只是內部函式儲存了乙份外部函式的變數值副本,但是以下 打破了我的認識 function createfunctions return result var funcs createfunctions for var i 0 i 10 i 執行結果是10個10 而不是0 9 看了js...

關於js的閉包

要理解上面的問題,首先要理解清楚幾個概念 來自 閉包裡的微觀世界 區別就是值型別變數是可以直接訪問棧 stack 中的值 接下來的內容就是關於閉包的微觀世界 function a return b var c a 函式a執行後返回函式b,並將函式b賦給c c 輸出 1 本來這個地方變數i是定義在函式...

對閉包的誤區

def func a 1def bibao a 1 return a return bibao c func c 錯誤 示例 這是因為在執行 c foo 時,python會匯入全部的閉包函式體bar 來分析其的區域性變數,python規則指定所有在賦值語句左面的變數都是區域性變數,則在閉包bar 中...