哆啦的时光机
在定义函数的时候,都做了哪些工作呢?Thereisnosillyquestion!这是一个好问题啊,ECMA标准里面有一节专门讲的就是这个问题。我在网上和书上都找了相关知识你确定你找对地方了么?这种问题不应该去看ECMA标准么?简单来说,在JavaScript中,因为函数是一等对象,定义函数的时候,实际上就是创建了一个对象,就这么简单!不过为了保证这个对象能够调用,它有几个特殊的内部属性/方法:[Call][[Construct]][[Scope]][[Code]][[FormalParameters]]当调用函数的时候,实际上就是调用该函数对象的[[Call]]内部方法;当使用new调用函数的时候,实际上就是调用该函数对象的[[Construct]]内部方法。定义函数时,{}之间的东西,不管是什么,哪怕是空的,全部原封不动地保存在[[Code]]内部属性里;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.调用函数时,LetresultbetheresultofevaluatingtheFunctionBodythatisthevalueofF's[[Code]]internalproperty.,才会对[[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.