版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
所謂閉包張立理
functioninfiniteSequence(){
vari=0;
return
function(){
return
i++;}}varincrement=infiniteSequence();console.log(increment());
console.log(increment());console.log(increment());//…WARNING!!WARNING非常非常的學術(shù)性大量術(shù)語詞匯出沒也許永遠都用不上內(nèi)容并非標準,有所刪減邏輯不是那么清晰只談函數(shù),不提eval,不提newFunctionSummary引言什么是變量閉包之表象閉包之內(nèi)在關(guān)于垃圾回收作用域的歷史ECMAScriptv3ScopeChainVariableObjectIdentifierResolutionECMAScriptv5LexicalEnvironmentVariableEnvironmentGetIdentifierReference什么是變量變量是一種關(guān)聯(lián)關(guān)系(association)關(guān)聯(lián)的目標:符號名(symbolicname)值(value)關(guān)聯(lián)是單向的–永遠不可能根據(jù)值找到變量Asymbolicnameassociatedwithavalueandwhoseassociatedvaluemaybechanged.--WikipediaIdentifiernameValue‘GrayZhang’什么是變量VariableStatementvarIdentifier=AssignmentExpressionFunctionDeclarationfunctionIdentifier(FormalParameterList){
FunctionBody
}FormalParameterListIdentifier,Identifier[,…]什么是變量varname=‘GrayZhang’;functionadd(x,y){
returnx+y;
}KeywordIdentifierValue(StringLiteral)閉包之表象內(nèi)層函數(shù)可以使用外層函數(shù)作用域內(nèi)的變量functionouter(){varname=‘GrayZhang’;functioninner(){console.log(‘Hello‘+name);}inner();}外層內(nèi)層閉包之內(nèi)在Q:為什么javascript會有閉包?A:因為ECMAScript中變量解析是一個查找過程,而非綁定過程。Q:變量存放在哪里?A:ExecutionContext中的VariableEnvironment。Q:從哪里查找變量?A:ExecutionContext中的LexicalEnvironment。Q:如何查找變量?A:自內(nèi)向外。?可執(zhí)行代碼(ExecutableCode)GlobalCodeFunctionCodeEvalCode<script>varname=‘GrayZhang’;varprefix=‘Hello‘;varphrases=[prefix,name];console.log(phrases.join(‘‘));</script>varsource=
‘varx=3;’+
‘console.log(x);’eval(source);functionsayHello(name){varprefix=‘Hello’;varphrases=[prefix,name];console.log(phrases.join(‘‘));}functiongetName(){varinput=$(‘#name’);returninput.val();}getName();執(zhí)行環(huán)境(ExecutionContext)當進入(開始執(zhí)行)一段可執(zhí)行代碼時,生成一個執(zhí)行環(huán)境對象。執(zhí)行環(huán)境對象通過棧(Stack)維護。新建的執(zhí)行環(huán)境對象稱為“當前運行的執(zhí)行環(huán)境對象”。functionenterCode(code){
varec=newExecutionContext();
control.ecStack.push(ec);
control.runningEC=ec;
control.execute(code);
}執(zhí)行環(huán)境(ExecutionContext)一個執(zhí)行環(huán)境對象包括:詞法環(huán)境–LexicalEnvironment變量環(huán)境–VariableEnvironmentThis綁定-ThisBindingExecutionContext:{LexicalEnvironment,VariableEnvironment,ThisBinding}詞法環(huán)境(LexicalEnvironment)既是一個屬性,又是一個類型。每個執(zhí)行環(huán)境對象都有且僅有一個關(guān)聯(lián)的詞法環(huán)境對象。在代碼執(zhí)行過程中,需要解析變量時,通過詞法環(huán)境對象進行解析,從其環(huán)境數(shù)據(jù)中得到值。一個詞法環(huán)境對象包括:環(huán)境數(shù)據(jù)–environementrecords外層環(huán)境–outerenvironment詞法環(huán)境(LexicalEnvironment)存在2種詞法環(huán)境的實現(xiàn)類型DeclarativeEnvironmentObjectEnvironment區(qū)別是ObjectEnvironment可接受指定的對象作為環(huán)境數(shù)據(jù)屬性的值?什么情況會出現(xiàn)ObjectEnvironment變量環(huán)境(VariableEnvironment)每個執(zhí)行環(huán)境對象都有且僅有一個關(guān)聯(lián)的變量環(huán)境對象。變量環(huán)境僅僅是一個名字,變量環(huán)境對象的類型是詞法環(huán)境(LexicalEnvironment)。在進入(開始執(zhí)行)代碼時,所有的變量標識符(Identifier)會存放在當前的變量環(huán)境對象中。變量環(huán)境中有環(huán)境數(shù)據(jù)屬性,但不使用外層環(huán)境屬性。環(huán)境數(shù)據(jù)(environmentrecords)存在于詞法環(huán)境或變量環(huán)境中。包含一個bindingobject,簡單地認為bindingobject是一個Map對象,保存變量標簽符(Identifier)和變量值(Value)的關(guān)系。常用方法:hadBinding(name)–查看是否有變量綁定createBinding(name)–創(chuàng)建一個變量綁定setBinding(name,value)–修改變量綁定的值getValue(name)–獲取變量綁定的值deleteBinding(name)–刪除一個變量綁定環(huán)境數(shù)據(jù)(environmentrecords)EnvironmentRecords:{bindingObject:{},hasBinding:function(name){return(nameinthis.bindingObject);},createBinding:function(name){this.bindingObject[name]=undefined;},setBinding:function(name,value){this.bindingObject[name]=value;},//…}環(huán)境數(shù)據(jù)(environmentrecords)存在2種環(huán)境數(shù)據(jù)的實現(xiàn)類型DeclarativeEnvironmentRecordsObjectEnvironmentRecordsLexicalEnvironmentEnvironmentRecordsObjectEnvironmentDeclaractiveEnvironmentObjectEnvironmentRecordsDeclaractiveEnvironmentRecords創(chuàng)建詞法環(huán)境NewDeclarativeEnvironment(e)用于創(chuàng)建一個DeclarativeEnvironment進入函數(shù)時執(zhí)行catch表達式時NewObjectEnvironment(o,e)用于創(chuàng)建一個ObjectEnvironment執(zhí)行with表達式時創(chuàng)建詞法環(huán)境functionNewDeclarativeEnvironment(e){varenv=newLexicalEnvironment();varenvRec=newEnvironmentRecords();envRec.bindingObject={};env.environmentRecords=envRec;env.outerEnvironment=e;returnenv;}functionNewObjectEnvironment(o,e){varenv=newLexicalEnvironment();varenvRec=newEnvironmentRecords();envRec.bindingObject=o;env.environmentRecords=envRec;env.outerEnvironment=e;returnenv;}消化一下名詞解釋完了嗎?NO總結(jié)ExecutionContext:{LexicalEnvironment,VariableEnvironment,ThisBinding}EnvironmentRecords:{hasBinding(name),createBinding(name),setBinding(name,value),getValue(name),deleteBinding(name)}LexicalEnvironment:{environmentRecords,outerEnvironment}函數(shù)(Function)是一個對象(Object)。包含幾個特殊的屬性[[Construct]]–newSomeFunction()[[Call]]–someFunction()[[HasInstance]]–oinstanceofSomeFunction[[Scope]]–閉包[[FormalParameters]]–參數(shù)列表[[Code]]–可執(zhí)行代碼包含可執(zhí)行代碼(ExecutableCode)和執(zhí)行狀態(tài)(State)。創(chuàng)建函數(shù)(CreateFunctionObject)新建一個普通對象(newObject())將[[Class]]設(shè)為”function”將[[Prototype]]指向Ftotype根據(jù)默認的規(guī)則,設(shè)置[[Call]]、[[Contruct]]及[[HasInstance]]屬性將[[Scope]]設(shè)置為當前的LexicalEnvironment對象設(shè)置[[Code]]、[[FormalParameterList]]及name、length、prototype屬性創(chuàng)建函數(shù)(CreateFunctionObject)varfn=newObject();//[[DefaultValue]],[[HasProperty]],etc...initializeAsObject(fn);fn.[[Class]]='function';fn.[[Prototype]]=Ftotype;fn.[[Call]]=function(){/*...*/};fn.[[Construct]]=function(){/*...*/};fn.[[HasInstance]]=function(){/*...*/};fn.[[Scope]]=control.runningEC.lexicalEnvironment;fn.[[Code]]=functionBody;fn.[[FormalParameterList]]=parameterList;=functionName;fn.length=parameterList.length;totype={constructor:fn};創(chuàng)建函數(shù)(CreateFunctionObject)作用域([[Scope]])是函數(shù)對象的一個屬性functionhello(){varo={};=‘GrayZhang’;returno;}varperson=hello();console.log();functionouter(){varname=‘GrayZhang’;functionsay(){alert(name);}returnsay;}varinner=outer();//inner.[[Scope]]inner();進入函數(shù)(EnteringFunctionCode)新建一個執(zhí)行環(huán)境。根據(jù)規(guī)則設(shè)置this綁定。如果thisArg是null或undefined,設(shè)置為global。如果thisArg不是Object,設(shè)置為ToObject(thisArg)。以函數(shù)的[[Scope]]屬性為參數(shù),NewDeclarativeEnvironment創(chuàng)建一個LexicalEnvironment對象。將當前LexicalEnvironment設(shè)置為該值。將當前VariableEnvironment設(shè)置為該值。開始初始化參數(shù)及函數(shù)內(nèi)聲明的變量。同一對象進入函數(shù)(EnteringFunctionCode)varec=newExecutionContext();if(thisArg==null){thisArg=global;}if(typeofthisArg!=='object'){thisArg=ToObject(thisArg);}ec.thisBinding=thisArg;varlocalEnv=NewDeclarativeEnvironment(fn.[[Scope]]);ec.lexicalEnvironment=localEnv;ec.variableEnvironment=localEnv;initializeBinding(fn.[[Code]],fn.[[FormalParameterList]]);進入函數(shù)(EnteringFunctionCode)執(zhí)行函數(shù)時,在作用域([[Scope]])的基礎(chǔ)上添加詞法環(huán)境(LexicalEnvironment)GlobalEnvironmentOuterEnvironmentCurrentEnvironment//GlobalEnvironmentfunctionouter(){//OuterEnvironmentfunctioninner(){//CurrentEnvironment}}varinner=outer();//[[Scope]]===OuterEnvironmentinner();定義綁定初始化
(DeclarationBindingInstantiation)從HostingBehavior說起……functionsayHello(name){if(!name){thrownewError();}else{varprefix='Hello';alert(prefix+name);}}functionsayHello(name){
varprefix;if(!name){thrownewError();}else{prefix='Hello';alert(prefix+name);}}定義綁定初始化
(DeclarationBindingInstantiation)遍歷FormalParameterList(參數(shù)列表),對每一項(參數(shù)),如果VariableEnvironment中不存在,則添加并賦值。依次遍歷源碼中每個FunctionDeclaration(函數(shù)聲明),對每一項(函數(shù)),如果VariableEnvironment中不存在,則添加,隨后賦值。如果VariableEnvironment中不存在arguments,則添加并賦值。依次遍歷源碼中每個VariableDeclaration(變量聲明),對每一項(變量),如果VariableEnvironment中不存在,則添加并賦值為undefined。定義綁定初始化
(DeclarationBindingInstantiation)functionformat(template,data){varregex=/\{(\w+)\:(\w+)\}/g;functionreplacer(match,name,type){varvalue=data[name];switch(type){case'boolean':value=!!value;break;case'html':value=encodeHTML(value);break;}returnvalue;}varhtml=template.replace(regex,replacer);returnhtml;}VariableEnvironmentarguments消化一下還有完沒完了!NO變量查找GetIdentifierReference(lex,name)從給定的LexicalEnvironment中查找是否存在該變量如果不存在,則從LexicalEnvironment的OuterEnvironment中查找依次進行,直到OuterEnvironment為null,則返回undefined返回一個Reference對象,通過GetValue進一步獲取變量的值變量查找functionGetIdentifierReference(lex,name){if(lex==null){returnnewReference(name,undefined);}varenvRec=lex.environmentRecords;if(envRec.hasBinding(name)){returnnewReference(name/*name*/,envRec/*base*/);}returnGetIdentifierReference(lex.outerEnvironment,name);}functionGetValue(reference){varenvRec=reference.base;returnenvRec.getValue();}大串燒進入全局環(huán)境創(chuàng)建全局執(zhí)行環(huán)境并入棧創(chuàng)建全局環(huán)境對象全局的詞法環(huán)境對象指向該對象全局的變量環(huán)境對象指向該對象在變量環(huán)境中添加outer綁定并賦值在變量環(huán)境中添加prefix綁定在變量環(huán)境中添加inner綁定//script…varprefix=‘Hello‘;functionouter(){varname=‘GrayZhang’;functionsay(){varmessage=prefix+name;alert(message);}returnsay;}varinner=outer();//inner.[[Scope]]inner();大串燒創(chuàng)建outer函數(shù)創(chuàng)建一個對象設(shè)置[[Call]]、[[Construct]]、[[HasInstance]]等設(shè)置[[Scope]]為當前詞法環(huán)境–全局環(huán)境設(shè)置[[Code]]、[[FormalParameterList]]等設(shè)置length、prototype等//script…varprefix=‘Hello‘;functionouter(){varname=‘GrayZhang’;functionsay(){varmessage=prefix+name;alert(message);}returnsay;}varinner=outer();//inner.[[Scope]]inner();大串燒GlobalEnvironmentouter:{[[Scope]]}inner:undefinedprefix:undefinedGlobalExecutionContextVariableEnvironmentLexicalEnvironment大串燒為prefix變量賦值在全局環(huán)境中尋找name綁定–找到得到上一步返回的Reference的base
–即全局環(huán)境的環(huán)境數(shù)據(jù)對象調(diào)用其setBinding(‘prefix’,‘Hello’)//script…varprefix=‘Hello‘;functionouter(){varname=‘GrayZhang’;functionsay(){varmessage=prefix+name;alert(message);}returnsay;}varinner=outer();//inner.[[Scope]]inner();大串燒GlobalEnvironmentouter:{[[Scope]]}inner:undefinedprefix:‘Hello‘GlobalExecutionContextVariableEnvironmentLexicalEnvironment大串燒執(zhí)行outer函數(shù)創(chuàng)建執(zhí)行環(huán)境并入棧創(chuàng)建一個詞法環(huán)境–DeclarativeEnvironmentouter的詞法環(huán)境對象指向該對象outer的變量環(huán)境對象指向該對象在變量環(huán)境中添加say綁定并賦值在變量環(huán)境中添加name綁定//script…varprefix=‘Hello‘;functionouter(){varname=‘GrayZhang’;functionsay(){varmessage=prefix+name;alert(message);}returnsay;}varinner=outer();//inner.[[Scope]]inner();大串燒創(chuàng)建say函數(shù)創(chuàng)建一個對象設(shè)置[[Call]]、[[Construct]]、[[HasInstance]]等設(shè)置[[Scope]]為當前詞法環(huán)境–outer的詞法環(huán)境設(shè)置[[Code]]、[[FormalParameterList]]等設(shè)置length、prototype等//script…varprefix=‘Hello‘;functionouter(){varname=‘GrayZhang’;
functionsay(){varmessage=prefix+name;alert(message);}returnsay;}varinner=outer();//inner.[[Scope]]inner();大串燒GlobalExecutionContextGlobalEnvironmentouter:{[[Scope]]}inner:undefinedprefix:‘Hello‘VariableEnvironmentLexicalEnvironmentOuterEnvironmentsay:{[[Scope]]}name:undefinedOuterExecutionContextVariableEnvironmentLexicalEnvironment大串燒為name變量賦值在outer的詞法環(huán)境中尋找name綁定–找到得到上一步返回的Reference的base
–即outer的詞法環(huán)境的環(huán)境數(shù)據(jù)對象調(diào)用其setBinding(‘name’,‘GrayZhang’)//script…varprefix=‘Hello‘;functionouter(){varname=‘GrayZhang’;functionsay(){varmessage=prefix+name;alert(message);}returnsay;}varinner=outer();//inner.[[Scope]]inner();大串燒GlobalEnvironmentouter:{[[Scope]]}inner:{[[Scope]]}prefix:‘Hello‘OuterEnvironmentsay:{[[Scope]]}name:‘GrayZhang’GlobalExecutionContextVariableEnvironmentLexicalEnvironmentOuterExecutionContextVariableEnvironmentLexicalEnvironment大串燒返回并賦值給inner變量將outer的ExecutionContext出棧在全局環(huán)境下尋找inner綁定–找到得到上一步返回的Reference的base–即全局環(huán)境的環(huán)境數(shù)據(jù)對象調(diào)用其setBinding(‘inner’,&say);//script…varprefix=‘Hello‘;functionouter(){varname=‘GrayZhang’;functionsay(){varmessage=prefix+name;alert(message);}returnsay;}varinner=outer();//inner.[[Scope]]inner();大串燒GlobalEnvironmentouter:{[[Scope]]}inner:{[[Scope]]}prefix:‘Hello‘OuterEnvironmentsay:{[[Scope]]}name:‘GrayZhang’GlobalExecutionContextVariableEnvironmentLexicalEnvironment大串燒執(zhí)行inner函數(shù)創(chuàng)建執(zhí)行環(huán)境并入棧創(chuàng)建一個詞法環(huán)境–DeclarativeEnvironmentinner的詞法環(huán)境對象指向該對象inner的變量環(huán)境對象指向該對象在變量環(huán)境中添加message綁定//script…varprefix=‘Hello‘;functionouter(){varname=‘GrayZhang’;functionsay(){varmessage=prefix+name;alert(message);}returnsay;}varinner=outer();//inner.[[Scope]]inner();大串燒GlobalEnvironmentouter:{[[Scope]]}inner:{[[Scope]]}prefix:‘Hello‘OuterEnvironmentsay:{[[Scope]]}name:‘GrayZhang’InnerEnvironmentmessage:undefinedGlobalExecutionContextVariableEnvironmentLexicalEnvironmentInnerExecutionContextVariableEnvironmentLexicalEnvironment大串燒為message變量賦值查找prefix變量的值在inner的詞法環(huán)境中尋找prefix綁定–沒有在outer的詞法環(huán)境中尋找prefix綁定–沒有在全局環(huán)境中尋找prefix綁定–找到取得prefix的值查找name變量的值…在inner的詞法環(huán)境中尋找message給message綁定賦值//script…varprefix=‘Hello‘;functionouter(){varname=‘GrayZhang’;functionsay(){varmessage=prefix+name;alert(message);}returnsay;}varinner=outer();//inner.[[Scope]]inner();大串燒GlobalEnvironmentouter:{[[Scope]]}inner:{[[Scope]]}prefix:‘Hello‘OuterEnvironmentsay:{[[Scope]]}name:‘GrayZhang’InnerEnvironmentmessage:‘HelloGrayZhang’GlobalExecutionContextVariableEnvironmentLexicalEnvironmentInnerExecutionContextVariableEnvironmentLexicalEnvironment大串燒獲取inner的值在inner的詞法環(huán)境中尋找message綁定–找到得到上一步返回的Reference的base
–即inner的詞法環(huán)境的環(huán)境數(shù)據(jù)對象調(diào)用該對象的getValue(‘message’)獲取alert的值…將inner作為參數(shù),調(diào)用alert函數(shù)//script…varprefix=‘Hello‘;functionouter(){varname=‘GrayZhang’;functionsay(){varmessage=prefix+name;alert(message);}returnsay;}varinner=outer();//inner.[[Scope]]inner();alert從何而來?大串燒functionborn(){varname='unknown';varage=1;return{setName:function(value){name=value;},grow:function(){age++;},print:function(){varparts=[name,age];varjoint='isnow';alert(parts.join(joint));}};}vargod=born();god.setName(‘leeight’);god.grow();god.grow();god.print();總結(jié)相關(guān)概念可執(zhí)行代碼–ExecutableCode執(zhí)行環(huán)境–ExecutionContext詞法環(huán)境–LexicalEnvironment變量環(huán)境–VariableEnvironment環(huán)境數(shù)據(jù)–EnvironmentRecords總結(jié)過程創(chuàng)建函數(shù)–[[Scope]][[Scope]]在創(chuàng)建時決定且不會變化進入函數(shù)–執(zhí)行環(huán)境+詞法環(huán)境+變量環(huán)境執(zhí)行時在最內(nèi)層增加詞法環(huán)境定義綁定初始化–參數(shù)+函數(shù)聲明+變量聲明變量環(huán)境和詞法環(huán)境是同一個對象變量查找–GetIdentifierReference延詞法環(huán)境自內(nèi)向外查找繼續(xù)消化我以為我懂了,直到……HowwithworksHowcatchworksHowletworksWhencodemeetsevalWhencodemeetsnewFunctionWhenthereisstrictmode從代碼說起functionouter(){varo=LargetObject.fromSize('400MB');returnfunction(){console.log('inner');};}varinner=outer();//對象圖此時對象之間的引用關(guān)系?GlobalFunctionLexicalEnvironmentEnvironmentRecordsBindingObjectLargeObjectinner[[Scope]]environmentRecordsbindingObjectoGlobal和o有間接引用,無法回收o但是事實上……functionouter(){vari=3;
returnfunction(){debugger;};}varinner=outer();inner();javascript引擎有能力回收i如果你是計算機……functionouter(){vari=3;varj=4;vark=5;functionprepare(){i=i+k;}functionhelp(){i=i+j;}
prepare();returnfunction(){help();console.log(i);};}varinner=outer();inner();i:不可回收j:不可回收k:可回收prepare:可回收help:不可回收人類的智商計算機的智商壓力好大~測試方法用斷點!Chrome/Firefox看內(nèi)存!IE/Opera一些基本結(jié)果IE6–8沒有回收閉包內(nèi)變量的機制Opera沒有回收閉包內(nèi)變量的機制Chrome回收閉包內(nèi)變量后,再次訪問該變量將拋出ReferenceErrorFirefox回收閉包內(nèi)變量后,再次訪問該變量會得到undefinedChrome、Firefox和IE9回收閉包內(nèi)變量的策略基本相同試問!有哪些因素可能導致變量無法回收?變量被返回的函數(shù)直接引用。變量被返回的函數(shù)間接引用(通過嵌套函數(shù))。返回的函數(shù)中有eval。返回的函數(shù)在with表達式建立的作用域中。返回的函數(shù)在catch表達式中。只談結(jié)果,不談過程!直接引用EngineCollectableChrome–V8NOFirefox–SpiderMonkeyNOIE9-ChakraNOfunctionouter(){vari=3;returnfunction(){i;};}varinner=outer();間接引用EngineCollectableChrome–V8NOFirefox–SpiderMonkeyNOIE9-ChakraNOfunctionouter(){vari=3;functionhelp(){i;}returnfunction(){help();};}varinner=outer();嵌套函數(shù)的平衡functionouter(){vari=0;functionhelp(){i++;}help();returnfunction(){console.log('nothing');}}varinner=outer();functionouter(){vari=0;functionhelp(){i++;returninner();}functioninner(){returni>3?i:help();}returninner();}varinner=outer();需要圖的遍歷需要處理環(huán)引用高成本+低效嵌套函數(shù)的平衡EngineCollectableChrome–V8NOFirefox–SpiderMonkeyNOIE9-ChakraNOfunctionouter(){vari=3;functionhelp(){i;}returnfunction(){};}varinner=outer();大惡魔evalfunctionouter(){vari=3;returnfunction(){returneval(‘i’);}
}varinner=outer();varresult=inner();console.log(result);//3?由字符串從詞法環(huán)境中獲取對象的唯一途徑可變性特殊性大惡魔evalvarreference=eval(‘someObject’);字符串分析varreference=eval(‘some’+‘Object’);常量預計算vars=‘some’;varreference=eval(s+‘Object’);變量->常量替換vararray=[‘some’,‘ject’];varreference=eval(array.join(‘Ob’));大惡魔evalfunctionouter(){vari=3;returnfunction(variableName){returneval(variableName);}
}varinner=outer();varinput=document.getElementById(‘variable_name’);varname=input.value.trim();varresult=inner(name);console.log(result);//3囧TooSimple,SometimesNative.大惡魔evalEngineCollectableChrome–V8NOFirefox–SpiderMonkeyNOIE9-ChakraNOfunctionouter(){vari=3;returnfunction(){eval(‘’);//無論eval的內(nèi)容是什么};}varinner=outer();間接eval和newFunction間接evalwindow.eval(coe)|(1,eval)(code)|(true&&eval)(code)InEdition5,indirectcallstotheevalfunctionusetheglobalenvironmentasboththevariableenvironmentandlexicalenvironmentfortheevalcode.newFunctionReturnanewFunctionobjectcreatedasspecifiedin13.2passingPastheFormalParameterListandbodyastheFunctionBody.PassintheGlobalEnvironmentastheScopeparameterandstrictastheStrictflag.間接eval和newFunctionvari=3;functionouter(){vari=4;returnfunction(){returnwindow.eval('i');/**varfn=newFunction('returni;');*returnfn();*/}}varinner=outer();varresult=inner();console.log(result);//3X間接eval和newFunctionEngineCollectabl
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- GB/T 44351-2024退化林修復技術(shù)規(guī)程
- 2024年度云南省高校教師資格證之高等教育心理學考前沖刺試卷A卷含答案
- 第5單元 圓 單元測試(含答案)2024-2025學年六年級上冊數(shù)學人教版
- 2024-2025學年廣東省部分學校高三(上)大聯(lián)考模擬預測物理試卷(含答案)
- 數(shù)據(jù)中心的未來發(fā)展
- 福建師范大學協(xié)和學院《生活藥學》2021-2022學年第一學期期末試卷
- 福建師范大學《政治學與行政學名著選讀》2022-2023學年第一學期期末試卷
- 福建師范大學《刑事案例與法條分析》2023-2024學年第一學期期末試卷
- 福建師范大學《全媒體現(xiàn)場主持實訓》2022-2023學年第一學期期末試卷
- 福建師范大學《國外社會保障制度概述》2023-2024學年第一學期期末試卷
- 城市管理知識競賽考試題庫200題(含答案)
- 北京市東城區(qū)六年級(上)期末語文試卷
- 鄉(xiāng)村振興農(nóng)村設(shè)計案例分析報告
- 【體能大循環(huán)】聚焦體能循環(huán)-探索運動奧秘-幼兒園探究體能大循環(huán)有效開展策略課件
- 《化工設(shè)備檢維修實訓》課程標準(煤炭清潔利用技術(shù))
- AI在航空航天領(lǐng)域中的應(yīng)用
- 餐飲員工心態(tài)培訓課件
- 2024年注冊消防工程師題庫及參考答案【完整版】
- 維護兒童心理健康的案例分析
- 中考英語一模作文-征集“文化自信類”寫作
- 打破性別刻板印象 課件-2023-2024學年高中下學期心理健康
評論
0/150
提交評論