国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

javascript - 關(guān)於閉包的理解?求解惑。
高洛峰
高洛峰 2017-05-18 10:49:50
0
4
625
function f1(){//2、找到 f1 函數(shù),執(zhí)行。
    var n=999;//3、給變量 n 賦值。
    nAdd=function(){n+=1}//9、找到 nAdd ,匿名函數(shù)內(nèi)沒有變量 n ,需要去上層查找,n = 999 +1。
    function f2(){//5、找到 f2 函數(shù),執(zhí)行。
        alert(n);//6、執(zhí)行動作。
    }
    console.log(n);//新加上,測試,不參與執(zhí)行步驟。
    return f2;//4、返回 f2 函數(shù),需要尋找 f2 函數(shù)。
}
var result=f1();//1、將 f1函數(shù)的返回值賦值給 result 變量,result 也變成函數(shù),需要尋找f1函數(shù)。
result(); //7、第一次執(zhí)行 result 函數(shù),將步驟 6 的執(zhí)行動作(步驟 6)結(jié)果輸出,n 等于 999。
nAdd();//8、執(zhí)行 f1 函數(shù)里的全局變量函數(shù) nAdd ,需要尋找 nAdd 函數(shù)。
result(); //10、第二次執(zhí)行 result 函數(shù),將步驟 5 的執(zhí)行動作(步驟 6)結(jié)果輸出,此時 n 等于 1000,因為第一次執(zhí)行 result 函數(shù)時,查找了上層的作用域,n 是 999。
nAdd();//11、如果再執(zhí)行 nAdd 函數(shù),此時 nAdd 這個函數(shù)里的 n 是 1000,而 f1 函數(shù)的 n 還是 999,也就是說 f1 的變量 n 和 nAdd 的 n 是兩個作用域不同的同名變量。
result(); 
f1();//新加上,測試

/*結(jié)果
控制臺輸出:999
彈窗:999
彈窗:1000
彈窗:1001
控制臺輸出:999
*/

想請教各位前輩看看這樣的理解是不是正確的。
補(bǔ)充:可不可以理解為,閉包第一次執(zhí)行的時候需要往上層查找變量,找到之後,上層的變量值就變成了子函數(shù)的變量值,以後就不需要再去上一層查找,因為已經(jīng)在第一次執(zhí)行的時候繼承了,變成自己的。
感覺有點亂。 。 。
(摀臉

--------------------再補(bǔ)充--------------------
越看越亂。
然後徹底亂了。
從輸出結(jié)果來看,第一次控制臺的輸出和最後一次控制臺的輸出,f1的 n 是不可變的。
但是子函數(shù)之間不是不能互相讀取變數(shù)嗎?為什麼 nAdd 的表達(dá)式會影響到 f2 的 n?

高洛峰
高洛峰

擁有18年軟件開發(fā)和IT教學(xué)經(jīng)驗。曾任多家上市公司技術(shù)總監(jiān)、架構(gòu)師、項目經(jīng)理、高級軟件工程師等職務(wù)。 網(wǎng)絡(luò)人氣名人講師,...

全部回覆(4)
某草草
function f1(){
    var n=999;
    nAdd=function(){n+=1}
    function f2(){
        alert(n);
    }
    console.log(n);
    return f2;
}
var result=f1();
result(); 
nAdd();
result();
nAdd();
result(); 
var b = f1();//新加上,測試

此時b和result中的n不是同一個
b和nAdd的n是同一個.
result的n已經(jīng)無法改變.

洪濤

有相同的問題,複製了下我的回答並添加一些。

  1. var result=f1():f1函數(shù)回傳了f2函數(shù)
    把回傳的f2函數(shù)賦值給result全域變量,(f2的作用域鏈保存到result全域變數(shù)中)

  2. result():呼叫result(),這就形成閉包:有權(quán)訪問另外一個函數(shù)作用域中的變量
    因為在f2中的作用域引用了f1中的n這個局部變量,當(dāng)f1執(zhí)行完畢之後,垃圾回收機(jī)制發(fā)現(xiàn)n變數(shù)還在被result引用所以垃圾回收機(jī)制不會把n回收釋放。
    以至於n一直保存在result作用域鏈中。 result的作用域鏈正常能存取f1中的局部變數(shù)n,形成閉包。

  3. nAdd():nAdd沒有寫var所以nAdd是全域變量,在呼叫nAdd()和result()是一樣的都會形成閉包,匿名函數(shù)function(){n+=1}的作用域鏈中有n這個局部變量,所以當(dāng)nAdd=funtion(){n+=1}時,這個匿名函數(shù)的作用域鏈保存到了全局變量nAdd形成閉包,調(diào)用nAdd()作用域鏈中找到f1局部變量n=999,n+ 1=1000。

  4. result():result()就輸出1000

  5. nAdd();重複第三步驟 n+1 = 1001

  6. result();重複第四步驟 輸出n

  7. f1();調(diào)用f1時並沒有形成閉包,n永遠(yuǎn)都是999,因為每次f1執(zhí)行結(jié)束後n都被垃圾回收機(jī)制銷毀了,所以這裡再次調(diào)用var n=999;後面輸出也都是999

為什麼 nAdd 的表達(dá)式會影響到 f2 的 n?
因為閉包的原因n一直都沒被銷毀,nAdd()也形成了閉包,並改變了n的值,所以後面再次調(diào)用result() n沒被銷毀回收一直被+1,所以會被影響。
最後在呼叫f1()時沒有閉包,之前n是被銷毀了。所以一直輸出a=999;

只是本人理解,如有錯誤請拍磚告知

黃舟

建議你看下這個
http://www.ruanyifeng.com/blo...
上面解釋得比較清楚

曾經(jīng)蠟筆沒有小新

說的太複雜了吧

這個閉包就是利用了js 的 static scope的特性實現(xiàn)的這個效果

function f1(){
    var n=999;// 這里標(biāo)識n 為代號 n1
    nAdd=function(){n+=1}+1。
    function f2(){
        alert(n);
    }
    console.log(n);
    return f2;
}
var result=f1();
result(); 
nAdd();
result(); 
nAdd();
result(); 
f1();

第一次呼叫result():

alert(n); 尋找的是 n1

nAdd(); 增加的也是n1的值

後面的也是這樣

而最後一次 f1();

運行的時候 var n = 999; 賦值的也是n1
其中console.log(n) 的n 也是n1 所以印出的就是999

你這個例子有點簡單,你可以看一個複雜的例子(重點看其中static scope)的說明:
static scope

最新下載
更多>
網(wǎng)站特效
網(wǎng)站源碼
網(wǎng)站素材
前端模板