中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

匿名函數和閉包

發布時間:2020-04-10 23:46:01 來源:網絡 閱讀:457 作者:jethai 欄目:開發技術




首先,一個函數不管是不是匿名函數,和閉包之間根本沒有任何關系!

所謂閉包究竟是什么?網絡上說法云里霧里,講得高深莫測,但是其實只要稍微有一些編譯器實現機制的認識,就會知道閉包其實是非常簡單的東西。

我們先來看看下面的代碼:

function funcA() {
    var a = 1, b = 2;
    return funcB();
     
    function funcB() {
        // 注意,a 和 b 在本函數里根本沒有定義,但是竟然能訪問到
        return a + b;
    }
}
 
var a = funcA();
// a 將會等于 3

上面的代碼神奇的地方有幾點:

1、函數可以嵌套定義(而 C/C++ 就不行)

2、嵌套的函數可以訪問到它的上級函數的局部變量


先說嵌套,其實這個能力沒什么神奇的,C/C++ 編譯器稍作修改就能支持,但是這么實現出來,雖然函數可以嵌套了,實用價值還是比較小,因為訪問不到上級函數的局部變量啊。而且我們知道 Javascript 的嵌套函數是可以層層嵌套的,而訪問時最內層的函數也能夠訪問到最頂層的函數的變量,非常有用!


說到這里,和閉包有什么關系呢?


閉包,就是用來實現這種嵌套時還能夠層層向上訪問變量的功能的!對的,它就是一個簡單的編譯器技巧,用來使得內部函數能夠訪問上級函數的變量。


簡單來說,它具體實現的方法為,在每個函數上附加上一個額外的隱藏對象,這個對象其實就叫做閉包對象,你別管他名字怎么叫,它就是個普通的對象!它沒什么神奇的,就是記錄了本函數內部的變量列表而已。而且這個閉包對象還保存了一個指向上級函數的閉包對象的引用。


這樣一來,就形成了一個鏈條。當我們在一個函數里訪問一個變量的時候,編譯器會先看看在本閉包里到底有沒有這個變量,如果沒有就向上尋找。如果找到,那就用,如果一直找到頭也沒有,那就提示出錯。


明白了嗎?就是這么回事。但是最后還有一點,按照上面的方式構造出來的閉包好像是固定的,其實每次調用一個函數的時候,都會單獨創建一個新的閉包對象和這一次調用對應起來。因此其實閉包鏈是動態創建的。


其實要說清楚這個問題,得配幾個圖。但是時間所限,我就不細說了。如果你能理解那最好,如果還是有疑問,那你以后慢慢接觸得多了就知道了。


最后解釋一下這段代碼,加深理解

function X() {
    return function() {
        // ...
    }
}


注意X里面這里返回了一個匿名函數。一定要記住這個函數由于是嵌套定義在 X 里的,因此它的閉包對象是鏈接到 X 的閉包對象上的,所以在這個匿名函數里是可以訪問到 X 內部的變量的。其實就是這么簡單。不管你嵌套多少層,匿名還是有名。我只看你定義時的嵌套關系,就知道閉包鏈的整個鏈條!其他就順理成章了。


最后推薦兩個讓你走出國內普遍存在的誤區的方法,一是多看 ECMA-262, 5e,這里面包含了所有標準化的 Javascript 的算法實現細節。另外一個是研究 Google 的 v8 引擎。自己下代碼下來編譯調試下,很多問題就能搞清楚了。


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

潜山县| 厦门市| 高密市| 蚌埠市| 兴山县| 积石山| 城步| 万荣县| 南汇区| 德州市| 恩施市| 安阳市| 剑川县| 小金县| 璧山县| 东山县| 万山特区| 彝良县| 富源县| 新竹县| 岚皋县| 永川市| 景德镇市| 云和县| 深泽县| 霍山县| 淳化县| 济阳县| 玉溪市| 金塔县| 宜兰市| 那坡县| 石林| 读书| 吉安县| 衡山县| 石河子市| 克什克腾旗| 郴州市| 万全县| 托克托县|