本文目錄一覽:
js閉包怎麼寫
var result=[];
function foo(){
var i= 0;
for (;i3;i=i+1){
result[i]=function(){
alert(i)
}
}
};
foo();
result[0](); // 3
result[1](); // 3
result[2](); // 3
這段代碼中,程序員希望foo函數中的變量i被內部循環的函數使用,並且能分別獲得他們的索引,而實際上,只能獲得該變量最後保留的值,也就是說.閉包中所記錄的自由變量,只是對這個變量的一個引用,而非變量的值,當這個變量被改變了,閉包里獲取到的變量值,也會被改變.
解決的方法之一,是讓內部函數在循環創建的時候立即執行,並且捕捉當前的索引值,然後記錄在自己的一個本地變量里.然後利用返回函數的方法,重寫內部函數,讓下一次調用的時候,返回本地變量的值,改進後的代碼:
var result=[];
function foo(){
var i= 0;
for (;i3;i=i+1){
result[i]=(function(j){
return function(){
alert(j);
};
})(i);
}
};
foo();
result[0](); // 0
result[1](); // 1
result[2](); // 2
北大青鳥java培訓:js解析機制與閉包分析?
隨着互聯網的不斷發展,程序員在學習JavaScript編程開發上也有了更多的了解,今天我們就簡單分析一下關於JavaScript編程解析機制以及閉包的一些常見問題。
js解析機制:js代碼解析之前會創建一個如下的詞法環境對象(倉庫):LexicalEnvironment{}在掃描js代碼時會把:1、用聲明的方式創建的函數的名字;2、用var定義的變量的名字存到這個詞法環境中;3、同名的時候:函數聲明會覆蓋變量,下面的函數聲明會覆蓋上面的同名函數;4、函數的值為:對函數的一個引用;變量的值為undefined;5、如果用函數表達式的方式創建一個函數:varfn=function(){}這樣詞法環境中存的是一個變量名fn,並賦值為undefined;在調用函數的時候如果在函數上面調用就會出現和變量一樣的情況報錯undefined;這也是以兩種不同方式創建函數的區別;閉包:定義:(有多種定義)1、(比較通俗的定義):函數嵌套函數,內部函數可以引用外部函數的參數和變量,這些參數和變量不會被垃圾回收機制所回收;2、在計算機科學中,閉包是詞法閉包的簡稱,是引用了自由變量的函數,這個被引用的自由變量將和這個函數一同存在,即使已經離開了創造它的環境也不例外(意思就是不會被銷毀)。
3、閉包是由函數和其相關的引用環境組合而成的實體。
(潛台詞就是這個函數將和引用環境同時存在,必須有引用)綜合來說,不管怎麼定義都是在圍繞着兩個本質:函數在引用變量,這個變量將不會被銷毀。
閉包的一個作用就是:我們能夠通過閉包的方法來在外部訪問到一個內部函數的變量;很多人在解釋閉包的時候都會把子函數return出去以後在外部調用,其實無論在哪裡調用,閉包都已經形成了,只要是函數嵌套函數,並且子函數引用了父函數的變量,(不論子函數有沒有被調用,電腦培訓認為這個用一種方法證明:在子函數內部打斷點,在f12中觀察閉包里的內容,已經出現了引用函數,這時候調用還沒有被執行)這個時候閉包已經形成了。
javascript中的window.ActiveXObject和閉包是什麼意思有什麼作用,在哪些情況下使用啊?
判斷瀏覽器是否支持ActiveX控件
閉包的兩個特點:
1、作為一個函數變量的一個引用 – 當函數返回時,其處於激活狀態。
2、一個閉包就是當一個函數返回時,一個沒有釋放資源的棧區。
例1。
scripttype=”text/javascript”
functionsayHello2(name){
vartext=’Hello’+name;//localvariable
varsayAlert=function(){alert(text);}
returnsayAlert;
}
varsy=sayHello2(‘never-online’);
sy();
/script
作為一個Javascript程序員,應該明白上面的代碼就是一個函數的引用。如果你還不明白或者不清楚的話,請先了解一些基本的知識,我這裡不再敘述。
上面的代碼為什麼是一個閉包?
因為sayHello2函數里有一個內嵌匿名函數
sayAlert = function(){ alert(text); }
在Javascript里。如果你創建了一個內嵌函數(如上例),也就是創建了一個閉包。
在C或者其它的主流語言中,當一個函數返回後,所有的局部變量將不可訪問,因為它們所在的棧已經被消毀。但在Javascript里,如果你聲明了一個內嵌函數,局部變量將在函數返回後依然可訪問。比如上例中的變量sy,就是引用內嵌函數中的匿名函數function(){ alert(text); },可以把上例改成這樣:
scripttype=”text/javascript”
functionsayHello2(name){
vartext=’Hello’+name;//localvariable
varsayAlert=function(){alert(text);}
returnsayAlert;
}
varsy=sayHello2(‘never-online’);
alert(sy.toString());
/script
這裡也就與閉包的第二個特點相吻合。
例2。
scripttype=”text/javascript”
functionsay667(){
//Localvariablethatendsupwithinclosure
varnum=666;
varsayAlert=function(){alert(num);}
num++;
returnsayAlert;
}
varsy=say667();
sy();
alert(sy.toString());
/script
上面的代碼中,匿名變量function() { alert(num); }中的num,並不是被拷貝,而是繼續引用外函數定義的局部變量——num中的值,直到外函數say667()返回。
例3。
scripttype=”text/javascript”
functionsetupSomeGlobals(){
//Localvariablethatendsupwithinclosure
varnum=666;
//Storesomereferencestofunctionsasglobalvariables
gAlertNumber=function(){alert(num);}
gIncreaseNumber=function(){num++;}
gSetNumber=function(x){num=x;}
}
/script
buttononclick=”setupSomeGlobals()”生成-setupSomeGlobals()/button
buttononclick=”gAlertNumber()”輸出值-gAlertNumber()/button
buttononclick=”gIncreaseNumber()”增加-gIncreaseNumber()/button
buttononclick=”gSetNumber(5)”賦值5-gSetNumber(5)/button
上例中,gAlertNumber, gIncreaseNumber, gSetNumber都是同一個閉包的引用,setupSomeGlobals(),因為他們聲明都是通過同一個全局調用——setupSomeGlobals()。
你可以通過“生成”,“增加”,“賦值”,“輸出值”這三個按扭來查看輸出結果。如果你點擊“生成”按鈕,將創建一個新閉包。也就會重寫gAlertNumber(), gIncreaseNumber(), gSetNumber(5)這三個函數。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/258036.html