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

資訊專欄INFORMATION COLUMN

一道JS前端閉包面試題解析

malakashi / 489人閱讀

摘要:當(dāng)執(zhí)行時(shí),對(duì)象也有一個(gè)閉包,引用了函數(shù)及外層函數(shù)變量,執(zhí)行輸出結(jié)果為能看懂前面的代碼執(zhí)行解釋,理解上面的代碼執(zhí)行輸出就不會(huì)有問(wèn)題了

問(wèn)題

代碼A

function fun(n,o){
    console.log(o);
    return {
        fun:function(m){//[2]
            return fun(m,n);//[1]
        }
    }
}

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è)閉包測(cè)試題

轉(zhuǎn)換為等價(jià)代碼

return返回的對(duì)象的fun屬性對(duì)應(yīng)一個(gè)新建的函數(shù)對(duì)象,這個(gè)函數(shù)對(duì)象將形成一個(gè)閉包作用域,使其能夠訪問(wèn)外層函數(shù)的變量n及外層函數(shù)fun,為了不將fun函數(shù)和fun屬性搞混,我們將上述代碼修改如下:
代碼B

function _fun_(n,o){
    console.log(o);
    return {
        fun:function(m){
            return _fun_(m,n);
        }
    }
}

var a=_fun_(0);//undefined
a.fun(1);//0
a.fun(2);//0
a.fun(3);//0

var b=_fun_(0).fun(1).fun(2).fun(3);
//undefined,0,1,2

var c=_fun_(0).fun(1);//undefined,0,
c.fun(2);//1
c.fun(3); //1

那么就有同學(xué)問(wèn)了,為什么可以這樣改呢,你怎么能確定[1]處的fun不是[2]代碼所在處的fun呢,要知道此處的fun屬性可是指向一個(gè)函數(shù)對(duì)象哦~
這里就要說(shuō)到JS的詞法作用域,JS變量作用域存在于函數(shù)體中即函數(shù)體,并且變量的作用域是在函數(shù)定義聲明的時(shí)候就是確定的,而非在函數(shù)運(yùn)行時(shí)。
如下代碼

var name="global";
function foo(){
    console.log(name);
}

function fooOuter1(){
    var name="local";
    foo();
}
fooOuter1();//輸出global 而不是local,并且和閉包沒(méi)有任何關(guān)系

function fooOuter2(){
    var name="local";
    function foo(){
        console.log(name);
    }
    foo();
}
fooOuter2();//輸出local 而不是global,在函數(shù)聲明是name變量作用域就在其外層函數(shù)中,嗯嗯就是閉包~

好了我們回到題目,在函數(shù)聲明定義階段,[2]處的匿名函數(shù)進(jìn)行定義聲明,發(fā)現(xiàn)在[1]處需要引用一個(gè)名為fun的函數(shù)對(duì)象,那么首先在當(dāng)前函數(shù)體內(nèi)尋找,發(fā)現(xiàn)沒(méi)有,那么就到其外層函數(shù)-這個(gè)匿名函數(shù)的包裹函數(shù)中去查找,發(fā)現(xiàn)也沒(méi)有,到外層函數(shù)中去,發(fā)現(xiàn)外面沒(méi)有函數(shù)包裹了,那就到全局環(huán)境下去找,額偶終于找到了......就把fun函數(shù)指定為全局環(huán)境下的fun函數(shù)對(duì)象并加入到匿名函數(shù)的閉包中去。至此我們就知道代碼B為什么和代碼A是等價(jià)的了~~~

創(chuàng)建閉包作用域

JS在詞法分析結(jié)束后,確定了1個(gè)閉包,就是返回的對(duì)象fun屬性對(duì)應(yīng)的匿名函數(shù)的閉包-訪問(wèn)全局環(huán)境下的_func_及其外層函數(shù)的函數(shù)內(nèi)部變量n;
在每次_func_執(zhí)行的時(shí)候,都會(huì)將閉包中變量的作用域信息傳遞到函數(shù)執(zhí)行環(huán)境中,供函數(shù)執(zhí)行時(shí)獲取變量值時(shí)使用

執(zhí)行輸出
var a=_fun_(0);//undefined
a.fun(1);//0
a.fun(2);//0
a.fun(3);//0

_fun_函數(shù)執(zhí)行,因?yàn)榈?個(gè)參數(shù)未定義,輸出undefined。然后返回一個(gè)對(duì)象,帶有fun屬性,指向一個(gè)函數(shù)對(duì)象-帶有閉包,能夠訪問(wèn)到_fun_和變量n_
a.fun(1)執(zhí)行返回的對(duì)象的fun方法,傳入m的值1,調(diào)用返回_fun_(1,0)
所以輸出為0,a.fun(2),a.fun(3)a.fun(1)

var b=_fun_(0).fun(1).fun(2).fun(3);

等價(jià)代碼

var b=_fun_(0);
var b1=b.fun(1);
var b2=b1.fun(2);//[3]
var b3=b2.fun(3);//[4]

前2句和上面的輸出相同undefined,0,當(dāng)[3]被調(diào)用時(shí),b1對(duì)象中有一個(gè)閉包,引用了_fun_函數(shù)及外層函數(shù)變量n=1,所以匿名函數(shù)執(zhí)行的函數(shù)調(diào)用為_(kāi)fun_(2,1),輸出結(jié)果為1,并返回一個(gè)新的對(duì)象。
當(dāng)[4]執(zhí)行時(shí),b2對(duì)象也有一個(gè)閉包,引用了_fun_函數(shù)及外層函數(shù)變量n=2,執(zhí)行_fun_(3,2),輸出結(jié)果為2

var c=fun(0).fun(1);//undefined,0,
c.fun(2);//1
c.fun(3); //1

能看懂前面的代碼執(zhí)行解釋,理解上面的代碼執(zhí)行輸出就不會(huì)有問(wèn)題了

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

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

相關(guān)文章

  • 一道js閉包面試的學(xué)習(xí)

    摘要:然后最外層這個(gè)函數(shù)會(huì)返回一個(gè)新對(duì)象,對(duì)象里面有一個(gè)屬性,名為,而這個(gè)屬性的值是一個(gè)匿名函數(shù),它會(huì)返回。 最近看到一條有意思的閉包面試題,但是看到原文的解析,我自己覺(jué)得有點(diǎn)迷糊,所以自己重新做一下這條題目。 閉包面試題原題 function fun(n, o) { // ① console.log(o); return { // ② fun: function(m) ...

    plus2047 評(píng)論0 收藏0
  • JavaScript系列(四) - 收藏集 - 掘金

    摘要:函數(shù)式編程前端掘金引言面向?qū)ο缶幊桃恢币詠?lái)都是中的主導(dǎo)范式。函數(shù)式編程是一種強(qiáng)調(diào)減少對(duì)程序外部狀態(tài)產(chǎn)生改變的方式。 JavaScript 函數(shù)式編程 - 前端 - 掘金引言 面向?qū)ο缶幊桃恢币詠?lái)都是JavaScript中的主導(dǎo)范式。JavaScript作為一門多范式編程語(yǔ)言,然而,近幾年,函數(shù)式編程越來(lái)越多得受到開(kāi)發(fā)者的青睞。函數(shù)式編程是一種強(qiáng)調(diào)減少對(duì)程序外部狀態(tài)產(chǎn)生改變的方式。因此,...

    cfanr 評(píng)論0 收藏0
  • 前端最強(qiáng)面經(jīng)匯總

    摘要:獲取的對(duì)象范圍方法獲取的是最終應(yīng)用在元素上的所有屬性對(duì)象即使沒(méi)有代碼,也會(huì)把默認(rèn)的祖宗八代都顯示出來(lái)而只能獲取元素屬性中的樣式。因此對(duì)于一個(gè)光禿禿的元素,方法返回對(duì)象中屬性值如果有就是據(jù)我測(cè)試不同環(huán)境結(jié)果可能有差異而就是。 花了很長(zhǎng)時(shí)間整理的前端面試資源,喜歡請(qǐng)大家不要吝嗇star~ 別只收藏,點(diǎn)個(gè)贊,點(diǎn)個(gè)star再走哈~ 持續(xù)更新中……,可以關(guān)注下github 項(xiàng)目地址 https:...

    wangjuntytl 評(píng)論0 收藏0
  • 2017 前端面試準(zhǔn)備 - 收藏集 - 掘金

    摘要:最近遇到的前端面試題更新版前端掘金個(gè)人博客已上線,歡迎前去訪問(wèn)評(píng)論無(wú)媛無(wú)故的個(gè)人博客以下內(nèi)容非本人原創(chuàng),是整理后覺(jué)得更容易理解的版本,歡迎補(bǔ)充。 一道面試題引發(fā)的對(duì) javascript 類型轉(zhuǎn)換的思考 - 前端 - 掘金 最近群里有人發(fā)了下面這題:實(shí)現(xiàn)一個(gè)函數(shù),運(yùn)算結(jié)果可以滿足如下預(yù)期結(jié)果: ... 收集 JavaScript 各種疑難雜癥的問(wèn)題集錦 - 前端 - 掘金 從原博客遷移...

    王晗 評(píng)論0 收藏0
  • 2017 前端面試準(zhǔn)備 - 收藏集 - 掘金

    摘要:最近遇到的前端面試題更新版前端掘金個(gè)人博客已上線,歡迎前去訪問(wèn)評(píng)論無(wú)媛無(wú)故的個(gè)人博客以下內(nèi)容非本人原創(chuàng),是整理后覺(jué)得更容易理解的版本,歡迎補(bǔ)充。 一道面試題引發(fā)的對(duì) javascript 類型轉(zhuǎn)換的思考 - 前端 - 掘金 最近群里有人發(fā)了下面這題:實(shí)現(xiàn)一個(gè)函數(shù),運(yùn)算結(jié)果可以滿足如下預(yù)期結(jié)果: ... 收集 JavaScript 各種疑難雜癥的問(wèn)題集錦 - 前端 - 掘金 從原博客遷移...

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

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

0條評(píng)論

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