資源描述:
《javascript從作用域鏈談閉包_javascript技巧》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在工程資料-天天文庫(kù)。
1、javascript從作用域鏈談閉包神馬是閉包關(guān)于閉包的概念,是婆說(shuō)婆有理。閉包是指冇權(quán)訪問(wèn)另外一個(gè)函數(shù)作用域中的變量的函數(shù)這概念有點(diǎn)繞,拆分一2從概念上說(shuō),閉包有兩個(gè)特點(diǎn):?1、函數(shù)?2、能訪問(wèn)另外一個(gè)函數(shù)作用域中的變量在ES6之前,Javascript只有函數(shù)作用域的概念,沒(méi)有塊級(jí)作用域(但calch捕獲的異常只能在catch塊中訪問(wèn))的概念(IIFE叮以創(chuàng)建局部作用域)。每個(gè)函數(shù)作用域都是封閉的,即外部是訪問(wèn)不到函數(shù)作用域小的變量。functiongetName(){varname=〃美女的名字〃;conso
2、le,log(name);//〃美女的名字〃}functiondisplayName(){console,log(name);//扌艮錯(cuò)}但是為了得到美女的名字,不死心的單身汪把代碼改成了這樣:functiongetName(){varname=〃美女的名字〃;funcliondisplayNameO{console?log(name);}returndisplayName;}var美女二getName();美女()//〃美女的名字〃這下,美女是一個(gè)閉包了,單身汪想怎么玩就怎么玩了。(但并不推薦單身汪用屮文做變量名
3、的寫法,大家不要學(xué))。關(guān)于閉包呢,還想再說(shuō)三點(diǎn):1、閉包可以訪問(wèn)當(dāng)前函數(shù)以外的變量functiongetOuter(){vardate='815,;functiongetDate(str){console.log(str+date);//訪問(wèn)外部的date}returngetDate(J今天是://"今天是:815〃}getOuter();getDate是一個(gè)閉包,該函數(shù)執(zhí)行時(shí),會(huì)形成一個(gè)作用域A,A中并沒(méi)有定義變量date,但它能在父一?級(jí)作用域小找到該變量的定義。2、即使外部函數(shù)已經(jīng)返回,閉包仍能訪問(wèn)外部函數(shù)定
4、義的變量functiongetOuter(){vardate二'815';functiongetDate(str){console.log(str+date);//訪問(wèn)外部的date}returngetDate;//外部函數(shù)返冋}vartoday二getOuter();todayC今天是://〃今天是:815〃today(J明天不是:’);//"明天不是:815〃3、閉包可以更新外部變量的值functionupdateCount(){varcount=0;functiongetCount(val){count=va
5、l;console,log(count);}returngctCount;//外部函數(shù)返回}varcount=updateCount();count(815);//815count(816);//816作用域鏈為毛閉包就能訪問(wèn)外部函數(shù)的變量呢?這就要說(shuō)說(shuō)Javascript屮的作用域鏈To__Javascript屮有一個(gè)執(zhí)行環(huán)境(executioncontext)的概念,它定義了變量或函數(shù)冇權(quán)訪問(wèn)的其它數(shù)據(jù),決定了他們各自的行為。每個(gè)執(zhí)行環(huán)境都冇一個(gè)與Z關(guān)聯(lián)的變量對(duì)彖,環(huán)境中定義的所有變量和函數(shù)都保存在這個(gè)對(duì)象中。
6、你可以把它當(dāng)做Javascript的一個(gè)普通對(duì)象,但是你只能修改它的屬性,卻不能引用它。變量對(duì)象也是有父作用域的。當(dāng)訪問(wèn)一個(gè)變量時(shí),解釋器會(huì)首先在當(dāng)前作用域查找標(biāo)示符,如果沒(méi)有找到,就去父作用域找,直到找到該變量的標(biāo)示符或者不再存在父作用域了,這就是作用域鏈。作用域鏈和原型繼承有點(diǎn)類似,但乂有點(diǎn)小區(qū)別:如果去查找一個(gè)普通對(duì)象的屬性吋,在當(dāng)前對(duì)象和其原型屮都找不到時(shí),會(huì)返冋undefined;但查找的屬性在作用域鏈中不存在的話就會(huì)拋出ReferenceError0作用域鏈的頂端是全局對(duì)象。對(duì)于全局環(huán)境中的代碼,作用域
7、鏈只包含一個(gè)元索:全局對(duì)象。所以,在全局環(huán)境中定義變量的時(shí)候,它們就會(huì)被定義到全局對(duì)象中。當(dāng)函數(shù)被調(diào)用的時(shí)候,作用域鏈就會(huì)包含多個(gè)作用域?qū)ο蟆?全局環(huán)境關(guān)于作用域鏈講得略多(紅皮書上有關(guān)于作用域及執(zhí)行環(huán)境的詳細(xì)解釋),看一個(gè)簡(jiǎn)單地例子://my_script?js"usestrict";varfoo二1;varbar二2;在全局環(huán)境小,創(chuàng)建了兩個(gè)簡(jiǎn)單地變量。如前而所說(shuō),此時(shí)變量對(duì)象是全局對(duì)象。?Non-nestedfunctions改動(dòng)一下代碼,創(chuàng)建一個(gè)沒(méi)有函數(shù)嵌套的函數(shù):〃usestrict";varfoo=1;
8、varbar=2;functionmyFunc(){//--define1ocal-to-functionvariablesvara=1;varb=2;varfoo=3;console.log(/zinsidemyFunc〃);}console.log(〃outside〃);//--andthen,callit:myFunc();當(dāng)myFunc被定義的時(shí)候,