最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時(shí)間:2015年12月25日 15:48:00   作者:kikong  
這篇文章主要針對(duì)一道JS前端閉包面試題進(jìn)行解析,從例題出發(fā)詳細(xì)介紹JS前端閉包相關(guān)知識(shí),感興趣的小伙伴們可以參考一下

問(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í)行解釋?zhuān)斫馍厦娴拇a執(zhí)行輸出就不會(huì)有問(wèn)題了,希望大家喜歡。

相關(guān)文章

  • js 文件引入實(shí)現(xiàn)代碼

    js 文件引入實(shí)現(xiàn)代碼

    項(xiàng)目前端的文件和后臺(tái)開(kāi)發(fā)分離,只要后臺(tái)開(kāi)發(fā)更新svn前端的js,css文件都會(huì)更新,以前引用的是一個(gè)js文件如AA.js,由于想在項(xiàng)目中引用jquery庫(kù),如果在每個(gè)文件的頭部都引讓他們從新寫(xiě)入這個(gè)jq文件不太可能
    2010-04-04
  • 拖動(dòng)層效果,兼容IE和FF!

    拖動(dòng)層效果,兼容IE和FF!

    拖動(dòng)層效果,兼容IE和FF!...
    2006-11-11
  • 前端日歷插件VCalendar的簡(jiǎn)單使用方法

    前端日歷插件VCalendar的簡(jiǎn)單使用方法

    這篇文章主要介紹了VCalendar的安裝和使用方法,包括如何通過(guò)官網(wǎng)地址引入API,并在項(xiàng)目中全局引入main.js文件,使用VCalendar可以實(shí)現(xiàn)日歷功能,需要的朋友可以參考下
    2025-01-01
  • antd upload控件的data參數(shù)使用

    antd upload控件的data參數(shù)使用

    這篇文章主要介紹了antd upload控件的data參數(shù)使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • 解決微信小程序云開(kāi)發(fā)中獲取數(shù)據(jù)庫(kù)的內(nèi)容為空的方法

    解決微信小程序云開(kāi)發(fā)中獲取數(shù)據(jù)庫(kù)的內(nèi)容為空的方法

    這篇文章主要介紹了解決微信小程序云開(kāi)發(fā)中獲取數(shù)據(jù)庫(kù)的內(nèi)容為空的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-05-05
  • JavaScript this綁定與this指向問(wèn)題的解析

    JavaScript this綁定與this指向問(wèn)題的解析

    本文主要介紹了JavaScript this綁定與this指向問(wèn)題的解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • javascript事件監(jiān)聽(tīng)與事件委托實(shí)例詳解

    javascript事件監(jiān)聽(tīng)與事件委托實(shí)例詳解

    這篇文章主要介紹了javascript事件監(jiān)聽(tīng)與事件委托,結(jié)合實(shí)例形式詳細(xì)分析了javascript事件監(jiān)聽(tīng)與事件委托相關(guān)原理、用法與操作注意事項(xiàng),需要的朋友可以參考下
    2019-08-08
  • 在微信小程序中使用iconfont的最新圖文教程

    在微信小程序中使用iconfont的最新圖文教程

    由于微信小程序線上的資源限制了各種接口安全域名,所以在小程序里如果想使用iconfont字體圖標(biāo)就會(huì)稍有不同,下面這篇文章主要給大家介紹了關(guān)于在微信小程序中使用iconfont的相關(guān)資料,需要的朋友可以參考下
    2022-08-08
  • ES6教程之for循環(huán)和Map,Set用法分析

    ES6教程之for循環(huán)和Map,Set用法分析

    這篇文章主要介紹了ES6教程之for循環(huán)和Map,Set用法,結(jié)合實(shí)例形式分析了ECMAScript6中for循環(huán)和Map,Set基本概念、功能、使用方法與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2017-04-04
  • 去除圖像或鏈接黑眼圈的兩種方法總結(jié)

    去除圖像或鏈接黑眼圈的兩種方法總結(jié)

    去除圖像或鏈接黑眼圈的兩種方法總結(jié)...
    2007-06-06

最新評(píng)論

墨玉县| 青铜峡市| 巴彦淖尔市| 合作市| 德昌县| 邵阳县| 旬阳县| 博野县| 库车县| 永仁县| 神木县| 丰原市| 永寿县| 湟中县| 梧州市| 乐平市| 河曲县| 且末县| 太仓市| 仁怀市| 龙南县| 新昌县| 阿克苏市| 星座| 岳阳市| 和静县| 贡山| 桦甸市| 镇远县| 芜湖县| 岳普湖县| 靖边县| 广平县| 平山县| 响水县| 都江堰市| 贵州省| 汉阴县| 平远县| 多伦县| 蒙城县|