在定義函數(shù)的時(shí)候,都做了哪些工作呢?Thereisnosillyquestion!這是一個(gè)好問題啊,ECMA標(biāo)準(zhǔn)里面有一節(jié)專門講的就是這個(gè)問題。我在網(wǎng)上和書上都找了相關(guān)知識(shí)你確定你找對(duì)地方了么?這種問題不應(yīng)該去看ECMA標(biāo)準(zhǔn)么?簡(jiǎn)單來說,在JavaScript中,因?yàn)楹瘮?shù)是一等對(duì)象,定義函數(shù)的時(shí)候,實(shí)際上就是創(chuàng)建了一個(gè)對(duì)象,就這么簡(jiǎn)單!不過為了保證這個(gè)對(duì)象能夠調(diào)用,它有幾個(gè)特殊的內(nèi)部屬性/方法:[Call][[Construct]][[Scope]][[Code]][[FormalParameters]]當(dāng)調(diào)用函數(shù)的時(shí)候,實(shí)際上就是調(diào)用該函數(shù)對(duì)象的[[Call]]內(nèi)部方法;當(dāng)使用new調(diào)用函數(shù)的時(shí)候,實(shí)際上就是調(diào)用該函數(shù)對(duì)象的[[Construct]]內(nèi)部方法。定義函數(shù)時(shí),{}之間的東西,不管是什么,哪怕是空的,全部原封不動(dòng)地保存在[[Code]]內(nèi)部屬性里;13.2CreatingFunctionObjectsGivenanoptionalparameterlistspecifiedbyFormalParameterList,abodyspecifiedbyFunctionBody,aLexicalEnvironmentspecifiedbyScope,andaBooleanflagStrict,aFunctionobjectisconstructedasfollows:CreateanewnativeECMAScriptobjectandletFbethatobject.Setalltheinternalmethods,exceptfor[[Get]],ofFasdescribedin8.12.Setthe[[Class]]internalpropertyofFto"Function".Setthe[[Prototype]]internalpropertyofFtothestandardbuilt-inFunctionprototypeobjectasspecifiedin15.3.3.1.Setthe[[Get]]internalpropertyofFasdescribedin15.3.5.4.Setthe[[Call]]internalpropertyofFasdescribedin13.2.1.Setthe[[Construct]]internalpropertyofFasdescribedin13.2.2.Setthe[[HasInstance]]internalpropertyofFasdescribedin15.3.5.3.Setthe[[Scope]]internalpropertyofFtothevalueofScope.LetnamesbeaListcontaining,inlefttorighttextualorder,theStringscorrespondingtotheidentifiersofFormalParameterList.Ifnoparametersarespecified,letnamesbetheemptylist.Setthe[[FormalParameters]]internalpropertyofFtonames.Setthe[[Code]]internalpropertyofFtoFunctionBody.Setthe[[Extensible]]internalpropertyofFtotrue.LetlenbethenumberofformalparametersspecifiedinFormalParameterList.Ifnoparametersarespecified,letlenbe0.Callthe[[DefineOwnProperty]]internalmethodofFwitharguments"length",PropertyDescriptor{[[Value]]:len,[[Writable]]:false,[[Enumerable]]:false,[[Configurable]]:false},andfalse.LetprotobetheresultofcreatinganewobjectaswouldbeconstructedbytheexpressionnewObject()whereObjectisthestandardbuilt-inconstructorwiththatname.Callthe[[DefineOwnProperty]]internalmethodofprotowitharguments"constructor",PropertyDescriptor{[[Value]]:F,{[[Writable]]:true,[[Enumerable]]:false,[[Configurable]]:true},andfalse.Callthe[[DefineOwnProperty]]internalmethodofFwitharguments"prototype",PropertyDescriptor{[[Value]]:proto,{[[Writable]]:true,[[Enumerable]]:false,[[Configurable]]:false},andfalse.IfStrictistrue,thenLetthrowerbethe[[ThrowTypeError]]functionObject(13.2.3).Callthe[[DefineOwnProperty]]internalmethodofFwitharguments"caller",PropertyDescriptor{[[Get]]:thrower,[[Set]]:thrower,[[Enumerable]]:false,[[Configurable]]:false},andfalse.Callthe[[DefineOwnProperty]]internalmethodofFwitharguments"arguments",PropertyDescriptor{[[Get]]:thrower,[[Set]]:thrower,[[Enumerable]]:false,[[Configurable]]:false},andfalse.ReturnF.NOTEAprototypepropertyisautomaticallycreatedforeveryfunction,toallowforthepossibilitythatthefunctionwillbeusedasaconstructor.調(diào)用函數(shù)時(shí),LetresultbetheresultofevaluatingtheFunctionBodythatisthevalueofF's[[Code]]internalproperty.,才會(huì)對(duì)[[Code]]屬性求值(evaluate)。13.2.1[[Call]]Whenthe[[Call]]internalmethodforaFunctionobjectFiscalledwithathisvalueandalistofarguments,thefollowingstepsaretaken:LetfuncCtxbetheresultofestablishinganewexecutioncontextforfunctioncodeusingthevalueofF's[[FormalParameters]]internalproperty,thepassedargumentsListargs,andthethisvalueasdescribedin10.4.3.LetresultbetheresultofevaluatingtheFunctionBodythatisthevalueofF's[[Code]]internalproperty.IfFdoesnothavea[[Code]]internalpropertyorifitsvalueisanemptyFunctionBody,thenresultis(normal,undefined,empty).ExittheexecutioncontextfuncCtx,restoringthepreviousexecutioncontext.Ifresult.typeisthrowthenthrowresult.value.Ifresult.typeisreturnthenreturnresult.value.Otherwiseresult.typemustbenormal.Returnundefined.