摘要:要理解閉包,首先得理解作用域。作用域主要分為兩種全局變量和局部變量。解決方法是,在退出函數(shù)之前,將不使用的局部變量全部刪除。但閉包的情況不同簡(jiǎn)而言之,閉包就是內(nèi)部函數(shù)和外部函數(shù)連接的一座橋梁,大人就是小孩與飯桌上所有菜的小助手。
閉包(closure)是Javascript語言的一個(gè)重點(diǎn),也是難點(diǎn),對(duì)于新手來說,概念過于抽象;而現(xiàn)在書上的大部分解釋都比較含糊,本文將把閉包掰開了、揉碎了講個(gè)清楚。
Tips:個(gè)人博客排版、UI更佳;地址:https://haonancx.github.io/js...
閉包閉包是指可以包含自由(未綁定到特定對(duì)象)變量的代碼塊;這些變量不是在這個(gè)代碼塊內(nèi)或者任何全局上下文中定義的,而是在定義代碼塊的環(huán)境中定義(局部變量)(百度百科)??? 這他娘叫講個(gè)清楚,別怕,讓我娓娓道來。
閉包,簡(jiǎn)單來說就是可以讀取其他函數(shù)內(nèi)部變量的函數(shù)。只要滿足這一點(diǎn)的函數(shù),都可以叫閉包。
要理解閉包,首先得理解作用域。
局部變量:只能用于定義它函數(shù)內(nèi)部。對(duì)于其他的函數(shù)或腳本代碼是不可用的。
{% highlight ruby %}
function myFunction() { var n = 5; return n * n; } myFunction();// 25
{% endhighlight %}
全局變量:函數(shù)可以訪問由函數(shù)內(nèi)部定義的變量。
{% highlight ruby %}
var n = 5; function myFunction() { return n * n; } myFunction();// 25
{% endhighlight %}
Javascript語言的特殊之處,就在于函數(shù)內(nèi)部可以直接讀取全局變量。例如:{% highlight ruby %}
var n=1; function example(){ alert(n); } f1(); // 1
{% endhighlight %}
另一方面,在函數(shù)外部自然無法讀取函數(shù)內(nèi)的局部變量。例如:{% highlight ruby %}
function example(){ var n=1; } alert(n); // error 報(bào)錯(cuò)
{% endhighlight %}
函數(shù)內(nèi)部聲明變量的時(shí)候,必須使用var命令去聲明一個(gè)變量。如果不用的話,就會(huì)聲明了一個(gè)全局變量。例如:{% highlight ruby %}
function example(){ n=1; } example(); alert(n); // 1
{% endhighlight %}
夾不到菜,怎么讓大人幫忙?就好比小孩在飯桌上吃飯,由于手比較短,只能在自己力所能及的范圍內(nèi)夾菜,也就是夾自己面前的菜(執(zhí)行環(huán)境);但是我們可以借用閉包(大人幫忙)的方式來夾別的菜。
當(dāng)我們需要得到函數(shù)內(nèi)的局部變量時(shí),正常情況下,是取不到的,只有通過巧妙的方法去實(shí)現(xiàn)。
廢話少說,上菜!!!
{% highlight ruby %}
function example(){ var n=1; function example2(){ alert(n); } return example2; } var result=example(); result(); // 1
{% endhighlight %}
好像有點(diǎn)明白了,但是怎么用呢?閉包不僅可以讀取函數(shù)內(nèi)部的變量,上面也提到了,還能讓這些變量的值始終保持在內(nèi)存中。
我們?cè)賮砜聪旅孢@個(gè)例子
{% highlight ruby %}
function example1(){ var n=1; Add=function() { n+=1 } function example2(){ alert(n); } return example2; } var result=example1(); result(); // 1 Add(); result(); // 2
{% endhighlight %}
由于閉包會(huì)使得函數(shù)中的變量都被保存在內(nèi)存中,內(nèi)存消耗很大,所以不能濫用閉包,否則會(huì)造成網(wǎng)頁的性能問題,在IE瀏覽器中可能導(dǎo)致內(nèi)存泄露。解決方法是,在退出函數(shù)之前,將不使用的局部變量全部刪除。
{% highlight ruby %}
function example() { var n = 1; return function(){ alert(n++) }; } fun();// 1 執(zhí)行完后 n++,變量n任然存在于內(nèi)存中 fun = null;// n被回收
{% endhighlight %}
閉包會(huì)在父函數(shù)外部,改變父函數(shù)內(nèi)部變量的值。所以,如果你把父函數(shù)當(dāng)作對(duì)象(object)使用,把閉包當(dāng)作它的公用方法(Public Method),把內(nèi)部變量當(dāng)作它的私有屬性(private value),這時(shí)一定要小心,不要隨便改變父函數(shù)內(nèi)部變量的值。
嵌套函數(shù)的閉包{% highlight ruby %}
function example() { var n = 1; return function(){ alert(n++) }; } var fun = example(); fun();// 1 執(zhí)行完后 n++,變量n任然存在于內(nèi)存中 fun();// 2 fun = null;// n被回收
{% endhighlight %}
閉包的缺點(diǎn)就是常駐內(nèi)存,閉包會(huì)使變量始終保存在內(nèi)存中,如果使用不當(dāng)會(huì)增大內(nèi)存使用量,很容易造成內(nèi)存泄露。
正常情況下外部函數(shù)是不能訪問內(nèi)部函數(shù)的變量的,但是可以利用閉包來實(shí)現(xiàn)對(duì)函數(shù)內(nèi)部變量的訪問。
一般函數(shù)執(zhí)行完畢后,局部活動(dòng)對(duì)象就被銷毀,內(nèi)存中僅僅保存全局作用域。但閉包的情況不同!
簡(jiǎn)而言之,閉包就是內(nèi)部函數(shù)和外部函數(shù)連接的一座橋梁,(大人就是小孩與飯桌上所有菜的小助手)。
該文章部分知識(shí)網(wǎng)絡(luò)整理文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/91234.html
摘要:使用上一篇文章的例子來說明下自由變量進(jìn)階期深入淺出圖解作用域鏈和閉包訪問外部的今天是今天是其中既不是參數(shù),也不是局部變量,所以是自由變量。 (關(guān)注福利,關(guān)注本公眾號(hào)回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo)) 本周正式開始前端進(jìn)階的第二期,本周的主題是作用域閉包,今天是第7天。 本計(jì)劃一共28期,每期重點(diǎn)攻克一個(gè)面試重難點(diǎn),如果你還不了解本進(jìn)階計(jì)...
摘要:如何使用閉包所以這時(shí)候我們就要用閉包去解決這個(gè)問題了,先看代碼。計(jì)數(shù)器為這時(shí)候的就形成了一個(gè)閉包。一個(gè)閉包由兩部分組成,函數(shù)和創(chuàng)建該函數(shù)的環(huán)境。就是創(chuàng)建了一個(gè)匿名函數(shù)調(diào)用函數(shù)解除對(duì)匿名函數(shù)的引用,以便釋放內(nèi)存 古老定義 閉包(closure),是指函數(shù)變量可以保存在函數(shù)作用域內(nèi),因此看起來是函數(shù)將變量包裹了起來。 //根據(jù)定義,包含變量的函數(shù)就是閉包 function foo() { ...
摘要:閉包面試題解由于作用域鏈機(jī)制的影響,閉包只能取得內(nèi)部函數(shù)的最后一個(gè)值,這引起的一個(gè)副作用就是如果內(nèi)部函數(shù)在一個(gè)循環(huán)中,那么變量的值始終為最后一個(gè)值。 (關(guān)注福利,關(guān)注本公眾號(hào)回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo)) 本周正式開始前端進(jìn)階的第二期,本周的主題是作用域閉包,今天是第8天。 本計(jì)劃一共28期,每期重點(diǎn)攻克一個(gè)面試重難點(diǎn),如果你還不了...
摘要:閉包一認(rèn)識(shí)閉包閉包是一種特殊的對(duì)象。它由兩部分構(gòu)成函數(shù),以及創(chuàng)建該函數(shù)的環(huán)境包含自由變量。環(huán)境由閉包創(chuàng)建時(shí)在作用域中的任何局部變量組成。創(chuàng)建閉包最常見方式,就是在一個(gè)函數(shù)內(nèi)部創(chuàng)建另一個(gè)函數(shù)。 閉包 showImg(https://segmentfault.com/img/bVbe3nk?w=1335&h=653); 一、認(rèn)識(shí)閉包 閉包是一種特殊的對(duì)象。它由兩部分構(gòu)成:函數(shù),以及創(chuàng)建該函...
摘要:以上是從作用域的角度對(duì)閉包的理解,我們還可以結(jié)合執(zhí)行上下文棧來理解閉包。這就是需要理解閉包的核心內(nèi)容。即,執(zhí)行到第行時(shí),全局上下文環(huán)境將變?yōu)榛顒?dòng)狀態(tài),但是上下文環(huán)境依然會(huì)在執(zhí)行上下文棧中。 理解了上下文環(huán)境、作用域、作用域鏈以及自由變量,我們?cè)賮砹牧拈]包。 我們不急于給出閉包的概念,先從應(yīng)用閉包的兩種情況 —— 1.函數(shù)作為返回值,2.函數(shù)作為參數(shù)被傳遞 —— 來直觀的認(rèn)識(shí)它。 第一,...
閱讀 2562·2023-04-25 18:13
閱讀 770·2021-11-22 12:10
閱讀 2970·2021-11-22 11:57
閱讀 2138·2021-11-19 11:26
閱讀 2164·2021-09-22 15:40
閱讀 1460·2021-09-03 10:28
閱讀 2704·2019-08-30 15:53
閱讀 1950·2019-08-30 15:44