成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

關(guān)于javascript中的閉包

myeveryheart / 2859人閱讀

摘要:在上面的執(zhí)行中,只是又返回了一個(gè)新的對(duì)象,但是并沒有執(zhí)行新對(duì)象里面的屬性對(duì)應(yīng)的匿名函數(shù)喔,那就是沒有改變的值啊,所以你繼續(xù)也會(huì)輸出同樣的結(jié)果啊。

關(guān)于javascript中的閉包
我GitHub上的菜鳥倉庫地址: 點(diǎn)擊跳轉(zhuǎn)查看其他相關(guān)文章
文章在我的博客上的地址: 點(diǎn)擊跳轉(zhuǎn)

? ? ? ? 其實(shí)關(guān)于閉包的定義,很多種說法,而關(guān)于閉包的解釋,更是多不勝數(shù)了。很多說得非常復(fù)雜,也有很多人有著不同的理解,在這里我就從最容易理解的角度去解釋閉包的概念,如有不正確的地方,請(qǐng)指出。

? ? ? ? 閉包,其實(shí)就是能夠讀取函數(shù)內(nèi)部變量的函數(shù)。

? ? ? ? 舉個(gè)例子:

//全局環(huán)境
function outer(){
    var big = 20;
}
console.log(big);

? ? ? ? 當(dāng)然了,執(zhí)行上面這樣的代碼會(huì)報(bào)錯(cuò),因?yàn)槟銢]有在全局環(huán)境中聲明big,你想訪問outer函數(shù)內(nèi)部的big也是不行的,因?yàn)槟銢]有調(diào)用outer函數(shù),壓根不會(huì)創(chuàng)建outer的執(zhí)行上下文,更不用說outer里面的big的作用域只是在outer函數(shù)內(nèi)部了。

? ? ? ? 那如何能夠在外部訪問到outer函數(shù)里面的big變量呢?有辦法,就是閉包:

//全局環(huán)境
function outer(){
    var big = 20;
    function inner(){
        console.log(big);
    };
    return inner();
}
outer();//20

? ? ? ? 你執(zhí)行outer函數(shù)的時(shí)候,里面返回的是調(diào)用inner函數(shù)的結(jié)果,而inner函數(shù)就是訪問big變量的,所以這樣就能使外部可以訪問到函數(shù)里面的變量。這就是所謂的閉包,沒有傳說中的那么復(fù)雜,不過網(wǎng)上的所謂閉包面試題就解釋得很復(fù)雜了。

? ? ? ? 但是閉包有一個(gè)問題,就是會(huì)使得你內(nèi)部訪問的變量常駐內(nèi)存當(dāng)中,垃圾機(jī)制又沒有將其回收,如果此函數(shù)不再使用了,又沒有對(duì)其進(jìn)行清除,就會(huì)造成內(nèi)存泄漏,如果過多使用閉包,后果可想而知。

? ? ? ? 其實(shí)換一個(gè)角度,我們看這樣的例子:

//全局環(huán)境
var bigger = 30;
function outer(){
    console.log(bigger);
}
outer();//30

? ? ? ? 像上面的例子,全局環(huán)境下聲明的outer函數(shù),里面調(diào)用了全局環(huán)境的bigger變量,不又是一個(gè)閉包嗎?其實(shí)沒錯(cuò),這是廣義的閉包,不是常說的閉包,但是轉(zhuǎn)頭想想,其實(shí)這個(gè)bigger是一直存在于全局的執(zhí)行上下文中的全局變量,你不清除掉不也一樣一直存在內(nèi)存中嗎?

? ? ? ? 一句話理解閉包類題目:如果a函數(shù)內(nèi)的其他b函數(shù)用到了a函數(shù)執(zhí)行上下文中的變量n,那么這個(gè)變量n的值就會(huì)一直保存在這個(gè)函數(shù)的變量對(duì)象當(dāng)中,直到下一次改變它。

? ? ? ? 舉個(gè)網(wǎng)上的面試?yán)觼碚f明我這個(gè)理解:

//全局環(huán)境
function fun(n,k) {
   console.log(k)
   return {
       fun:function(m){
           return fun(m,n);
       }
   };
}
var a = fun(0); a.fun(1); a.fun(2); a.fun(3);
var b = fun(0).fun(1).fun(2).fun(3);
var c = fun(0).fun(1); c.fun(2); c.fun(3);

? ? ? ? 這個(gè)例子也是隨便一搜的,其他例子其實(shí)也類同,所以在這里就用我個(gè)人理解的角度去分析一下這個(gè)題。

? ? ? ? 先說var a 這一行的輸出吧:

? ? ? ? var a = fun(0)很容易知道輸出undefined了,但是返回的是一個(gè)對(duì)象,這個(gè)對(duì)象的fun屬性是一個(gè)匿名函數(shù),而這個(gè)匿名函數(shù)里面又返回了一個(gè)fun函數(shù),這個(gè)fun函數(shù)用到了變量n。好了,用上我前面的理解,可以知道fun函數(shù)里面就保存了n=0這個(gè)值,直到下一次改變它。類似如下:

var a = {
    fun:function(m){
       return fun(m,0);
    }
};

? ? ? ? 而從a.fun(1)、a.fun(2)、 a.fun(3)開始,大家肯定知道會(huì)執(zhí)行這三個(gè)函數(shù):

f(1,0);f(2,0);f(3,0);

? ? ? ? 所以會(huì)輸出undefined ?0 ?0 ?0。

? ? ? ? 可能大家會(huì)懵了,你在執(zhí)行f(1,0)的時(shí)候,不是n的值改為1,不是會(huì)改變了n的值了嗎?后面的n的值不是變了嗎?在這里我就要說說關(guān)于我的理解中,怎樣為改變這個(gè)變量的值。

? ? ? ? 先再回顧一下我前面的理解:如果a函數(shù)內(nèi)的其他b函數(shù)用到了a函數(shù)執(zhí)行上下文中的變量n,那么這個(gè)變量n的值就會(huì)一直保存在這個(gè)函數(shù)的變量對(duì)象當(dāng)中,直到下一次改變它

? ? ? ? 改變這個(gè)變量的n值,必須通過閉包,也就是這個(gè):

{
     fun:function(m){
         return fun(m,n);
     }
};

? ? ? ? 通過這個(gè)fun屬性對(duì)應(yīng)的匿名函數(shù)的執(zhí)行,才會(huì)在匿名函數(shù)的返回結(jié)果中改變這個(gè)n的值。

? ? ? ? 在上面的執(zhí)行a.fun(1)中,只是又返回了一個(gè)新的對(duì)象,但是并沒有執(zhí)行新對(duì)象里面的fun屬性對(duì)應(yīng)的匿名函數(shù)喔,那就是沒有改變n的值啊,所以你繼續(xù)a.fun(2)、a.fun(3)也會(huì)輸出同樣的結(jié)果啊。

? ? ? ? 也就是,必須有執(zhí)行這樣:a.fun(1).fun(1)這樣,才會(huì)改變到n的值。

? ? ? ? 對(duì)于上面例題var b這一行來說,就很容易明白var b = fun(0).fun(1).fun(2).fun(3);后面的fun(1).fun(2).fun(3)這三個(gè)中的fun其實(shí)都是屬性名fun,并不是聲明的函數(shù)fun,所以他們都在改變n的值啊,所以也很容易明白這一行的輸出結(jié)果就是undefined ?0 ?1 ?2。

? ? ? ? var c的那一行也很容易明白輸出結(jié)果是undefined ?0 ?1 ?1了。

? ? ? ? 關(guān)于這個(gè)題的詳細(xì)理解,大家再細(xì)想一下,就很清楚了。

?

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/87326.html

相關(guān)文章

  • 前端基礎(chǔ)進(jìn)階(四):詳細(xì)圖解作用域鏈與閉包

    摘要:之前一篇文章我們?cè)敿?xì)說明了變量對(duì)象,而這里,我們將詳細(xì)說明作用域鏈。而的作用域鏈,則同時(shí)包含了這三個(gè)變量對(duì)象,所以的執(zhí)行上下文可如下表示。下圖展示了閉包的作用域鏈。其中為當(dāng)前的函數(shù)調(diào)用棧,為當(dāng)前正在被執(zhí)行的函數(shù)的作用域鏈,為當(dāng)前的局部變量。 showImg(https://segmentfault.com/img/remote/1460000008329355);初學(xué)JavaScrip...

    aikin 評(píng)論0 收藏0
  • 淺談對(duì)JavaScript閉包的理解

    摘要:關(guān)于循環(huán)和閉包當(dāng)循環(huán)和閉包結(jié)合在一起時(shí),經(jīng)常會(huì)產(chǎn)生讓初學(xué)者覺得匪夷所思的問題。閉包是一把雙刃劍是比較難以理解和掌握的部分,它十分強(qiáng)大,卻也有很大的缺陷,如何使用它完全取決于你自己。 在談閉包之前,我們首先要了解幾個(gè)概念: 什么是函數(shù)表達(dá)式? 與函數(shù)聲明有何不同? JavaScript查找標(biāo)識(shí)符的機(jī)制 JavaScript的作用域是詞法作用域 JavaScript的垃圾回收機(jī)制 先來...

    missonce 評(píng)論0 收藏0
  • JavaScript深入淺出

    摘要:理解的函數(shù)基礎(chǔ)要搞好深入淺出原型使用原型模型,雖然這經(jīng)常被當(dāng)作缺點(diǎn)提及,但是只要善于運(yùn)用,其實(shí)基于原型的繼承模型比傳統(tǒng)的類繼承還要強(qiáng)大。中文指南基本操作指南二繼續(xù)熟悉的幾對(duì)方法,包括,,。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。 怎樣使用 this 因?yàn)楸救藢儆趥吻岸耍虼宋闹兄豢炊?8 成左右,希望能夠給大家?guī)韼椭?...(據(jù)說是阿里的前端妹子寫的) this 的值到底...

    blair 評(píng)論0 收藏0
  • JavaScript閉包初探

    摘要:說了半天,究竟什么是閉包呢閉包就是函數(shù)的局部變量集合,只是這些局部變量在函數(shù)返回后會(huì)繼續(xù)存在。彈出上面函數(shù)中的函數(shù)就是閉包,就是通過建立函數(shù)來訪問函數(shù)內(nèi)部的局部變量。閉包會(huì)在父函數(shù)外部,改變父函數(shù)內(nèi)部變量的值。 JavaScript的閉包 首先聲明,這是一篇面向小白的博客,不過也歡迎各位大牛批評(píng)指正,謝謝。 ??其實(shí)關(guān)于閉包各個(gè)論壇社區(qū)里都有很多的文章來講它,畢竟閉包是JavaScri...

    沈建明 評(píng)論0 收藏0
  • JavaScript閉包初探

    摘要:說了半天,究竟什么是閉包呢閉包就是函數(shù)的局部變量集合,只是這些局部變量在函數(shù)返回后會(huì)繼續(xù)存在。彈出上面函數(shù)中的函數(shù)就是閉包,就是通過建立函數(shù)來訪問函數(shù)內(nèi)部的局部變量。閉包會(huì)在父函數(shù)外部,改變父函數(shù)內(nèi)部變量的值。 JavaScript的閉包 首先聲明,這是一篇面向小白的博客,不過也歡迎各位大牛批評(píng)指正,謝謝。 ??其實(shí)關(guān)于閉包各個(gè)論壇社區(qū)里都有很多的文章來講它,畢竟閉包是JavaScri...

    canger 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<