前端-階段一所謂閉包_第1頁
前端-階段一所謂閉包_第2頁
前端-階段一所謂閉包_第3頁
前端-階段一所謂閉包_第4頁
前端-階段一所謂閉包_第5頁
已閱讀5頁,還剩83頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(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非常非常的學(xué)術(shù)性大量術(shù)語詞匯出沒也許永遠都用不上內(nèi)容并非標(biāo)準(zhǔn),有所刪減邏輯不是那么清晰只談函數(shù),不提eval,不提newFunctionSummary引言什么是變量閉包之表象閉包之內(nèi)在關(guān)于垃圾回收作用域的歷史ECMAScriptv3ScopeChainVariableObjectIdentifierResolutionECMAScriptv5LexicalEnvironmentVariableEnvironmentGetIdentifierReference什么是變量變量是一種關(guān)聯(lián)關(guān)系(association)關(guān)聯(lián)的目標(biāo):符號名(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)當(dāng)進入(開始執(zhí)行)一段可執(zhí)行代碼時,生成一個執(zhí)行環(huán)境對象。執(zhí)行環(huán)境對象通過棧(Stack)維護。新建的執(zhí)行環(huán)境對象稱為“當(dāng)前運行的執(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í)行)代碼時,所有的變量標(biāo)識符(Identifier)會存放在當(dāng)前的變量環(huán)境對象中。變量環(huán)境中有環(huán)境數(shù)據(jù)屬性,但不使用外層環(huán)境屬性。環(huán)境數(shù)據(jù)(environmentrecords)存在于詞法環(huán)境或變量環(huán)境中。包含一個bindingobject,簡單地認為bindingobject是一個Map對象,保存變量標(biāo)簽符(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è)置為當(dāng)前的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對象。將當(dāng)前LexicalEnvironment設(shè)置為該值。將當(dāng)前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]]為當(dāng)前詞法環(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]]為當(dāng)前詞法環(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)變量的策略基本相同試問!有哪些因素可能導(dǎo)致變量無法回收?變量被返回的函數(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’);常量預(yù)計算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)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論