閉包概念集合

2022-04-10 19:23:01 字數 2589 閱讀 2724

一、建立閉包

建立閉包的常見方式,就是在乙個函式內部建立另乙個函式。

二、作用域鏈

當某個函式被呼叫的時候,會建立乙個執行環境和相應的作用域鏈,然後使用arguments初始化物件。這個物件叫做活動物件。

在作用域鏈中,外部函式的活動物件始終處於第二位。以此類推,直到作用域鏈終點——全域性執行環境。 首先,讓我先來看看什麼叫做活動物件。

function

compare(a,b)

else

if(aelse

}var result=compare(5,10);//

false

console.log(result);

這段**中,首先定義了compare()函式,然後在全域性作用域中呼叫了它。在呼叫這個函式的時候,建立了arguments、a、b這三個活動物件。他們處在作用域鏈的第一位。

而result、compare被稱為變數物件,他們處於全域性執行環境下,在作用域鏈中處於第二位。

全域性環境的變數物件始終存在,在函式中訪問乙個變數時,就會在作用域鏈中尋找具有相應名字的變數。函式執行完畢,活動物件就被銷毀。而閉包的特殊就在於此,活動物件沒有被銷毀!

看這段**:

function

compare(propertyvalue)

else

if(a>b)

else

}}var fun=compare("value");

console.log(

typeof fun);//

function

var result=fun(5,10);

console.log(result);

//true

函式compare()中包含了乙個匿名函式,那麼,該匿名函式,也就是閉包的作用域鏈中,就會有compare()函式的活動物件。因此,該閉包作用域鏈其實有三節:

第一節,閉包的活動物件,obj1,obj2 和arguments;

第二節,compare()函式的活動物件,arguments和propertyvalue;

第三節,全域性變數物件,compare。

這意味著什麼意思呢?就是在compare()這個函式在執行完畢以後,他的活動物件propertyvalue和arguments也不會被銷毀。因為匿名函式的作用域鏈仍然在引用這個活動物件。也就是說,compare()執行完以後,其執行環境的作用域鏈會被銷毀,但是他的活動物件卻不會被銷毀

。除非匿名函式被銷毀。

而在js中,內建的工具函式settimeout,往往就會造就乙個閉包。

function

wait(message),1000);

}wait('5');//

5

timer()函式就是乙個閉包,即使wait()執行1000毫秒後,內部作用域仍然不會消失。timer具有wait()作用域的閉包。

三、閉包與變數

function

fun();

}return

result;

}var a=fun();

console.log(a);

//array(4) [, , , ]

好吧,這段**我還是看的半懂不懂。似乎理解他為什麼會返回這個,似乎又不理解。而且和書上寫的也不一樣啊。也沒返回4個「3」啊!這是為啥內?

for(var i=0;i<2;i++),i*1000);

}console.log('daoda')//

daoda;2;2

看到沒有,竟然先輸出了"daoda",然後又輸出了兩個「2」!

首先解釋「2」是怎麼來的。首先,這個迴圈終止的條件是i不再小於2,也就是說,條件首次成立時,i的值為2。因此,輸出顯示的是迴圈結束時i的值。

延遲函式的**是在迴圈結束的時候才執行。即使執行的是settimeout(...,0),所有的**函式依然是在迴圈結束後才會執行。因此每次輸出的都是2!

你以為每次迭代都會有對應的i,但是根據作用域的原理,儘管迴圈中的5個函式是在各個迭代部分中分別定義的,但是它們卻都被封閉在乙個共享的全域性作用域中,因此實際上只有1個i。

for(var i=0;i<2;i++),i*1000);

})();

}console.log('藍色橙汁');//

"藍色橙汁";2;2

iife會立即執行函式,為什麼輸出的還是兩個「2」呢?

這是因為iife的作用域是空的。他要有自己的變數,用來在每次迭代中儲存i的值才行。

**寫成這樣才可以:

for(var i=1;i<=5;i++),j*1000);

})();

}

上面這段**可以做一些改進:

for(var i=1;i<=5;i++),j*1000);

})(i);

}

奇怪的是,為什麼這裡我就理解了?

閉包的概念

因此 可以訪問外部函式的變數,其內部變數只能內部可訪問 閉包時塊級作用域,可以定義自己的變數,避免變數命名衝突,汙染外部變數 使用場景一 封裝私有變數,對外暴露get,set方法或其中一種 使用場景二 儲存外部函式的變數 使用場景三 使用場景三 當閉包被賦值給乙個生命較長的變數時,其所依賴的父函式的...

閉包的概念 轉

首先,我覺得,乙個概念,如果不理解也不影響使用的話,那麼,就沒必要去理解它 去學習它。閉包就是這樣乙個概念,你不理解它也能很好的用它。俺這兩年寫as3程式,是天天在和它打交道,甚至有過乙個function套乙個,乙個方法中套了20多個function的極端例子,但從未深究過它是怎麼實現的,它就像水和...

js 閉包概念,用法

1 我們常說的閉包就是函式巢狀函式,內部函式可以引用外部函式的引數和變數 如下 2 會涉及到js中的垃圾 機制 指 當函式執行完時,函式的變數將會收回,閉包就不一樣了 如下 3 閉包中當外部函式載入完時,外部函式的變數內部函式還可以繼續使用,不會 如下 4 閉包的好處 將乙個變數長期駐紮在記憶體中 ...