语法
''<b id="FunctionDeclaration">FunctionDeclaration</b>'' : '''function''' ''[[ES5/lexical#Identifier|Identifier]]'' '''(''' ''{{toanchor|FormalParameterList}}<sub>opt</sub>'' ''')''' '''{''' ''{{toanchor|FunctionBody}}'' '''}'''
''<b id="FunctionExpression">FunctionExpression</b>'' : '''function''' ''[[ES5/lexical#Identifier|Identifier]]<sub>opt</sub>'' '''(''' ''{{toanchor|FormalParameterList}}<sub>opt</sub>'' ''')''' '''{''' ''{{toanchor|FunctionBody}}'' '''}'''
''<b id="FormalParameterList">FormalParameterList</b>'' : ''[[ES5/lexical#Identifier|Identifier]]'' ''{{toanchor|FormalParameterList}}'' ''',''' ''[[ES5/lexical#Identifier|Identifier]]''
''<b id="FunctionBody">FunctionBody</b>'' : ''[[ES5/program#SourceElements|SourceElements]]<sub>opt</sub>''
语义
产生式 : function Identifier ( opt ) { } 依照定义绑定初始化 (10.5) 如下初始化:
- 依照 13.2,指定 opt 为<var>参数列表</var>,指定 为 <var>函数体</var>,创建一个新函数对象,返回结果。运行中的执行环境的 VariableEnvironment 传递为 <var>Scope</var>。如果 包含在严格模式代码里或 是严格模式代码,那么传递 true 为 <var>Strict</var> 标志。
- 依照 13.2,指定 opt 为<var>参数列表</var>,指定 为 <var>函数体</var>,创建一个新函数对象,返回结果。运行中的执行环境的 LexicalEnvironment 传递为 <var>Scope</var>。如果 包含在严格模式代码里或 是严格模式代码,那么传递 true 为 <var>Strict</var> 标志。
- 令 <var>funcEnv</var> 为以运行中执行环境的 LexicalEnvironment 为参数调用 NewDeclarativeEnvironment 的结果。
- 令 <var>envRec</var> 为 <var>funcEnv</var> 的环境记录项。
- 以 Identifier 的字符串值为参数调用 <var>envRec</var> 的具体方法 CreateImmutableBinding(N)。
- 令 <var>closure</var> 为依照 13.2,指定 opt 为参数,指定 为 <var>函数体</var>,创建一个新函数对象的结果。传递 <var>funcEnv</var> 为 <var>Scope</var>。如果 包含在严格模式代码里或 是严格模式代码,那么传递 true 为 <var>Strict</var> 标志。
- 以 Identifier 的字符串值和 <var>closure</var> 为参数调用 <var>envRec</var> 的具体方法 InitializeImmutableBinding(N,V)。
- 返回 <var>closure</var>。
- 如果这个 所在 或 包含在严格模式代码内,或其 SourceElements 的指令序言(14.1)包含一个 use strict 指令,或满足 10.1.1 的任何条件,那么其代码严格模式代码。如果 的代码是严格模式代码,SourceElements 的解释执行为以下的严格模式代码步骤。否则,SourceElements 的解释执行为以下的非严格模式代码。
- 如果 SourceElements 存在,则返回 SourceElements 的解释执行结果。
- 否则返回 (normal, undefined, empty)。
如果严格模式 或 的 里出现多个相同 Identifier 值,那么这是个 SyntaxError。
如果严格模式 或 的 里出现标识符 "eval" 或标识符 "arguments",那么这是个 SyntaxError。
如果严格模式 或 的 Identifier 是标识符 "eval" 或标识符 "arguments",那么这是个 SyntaxError。
指定 为可选的 <var>参数列表</var>,指定 为 <var>函数体</var>,指定 <var>Scope</var> 为词法环境,<var>Strict</var> 为布尔标记,按照如下步骤构建函数对象:
- 创建一个新的 ECMAScript 原生对象,令 <var>F</var> 为此对象。
- 依照 8.12 描述设定 <var>F</var> 的除 [[Get]] 以外的所有内部方法。
- 设定 <var>F</var> 的 [[Class]] 内部属性为 "Function"。
- 设定 <var>F</var> 的 [[Prototype]] 内部属性为 15.3.3.1 指定的标准内置 Function 对象的 prototype 属性。
- 依照 15.3.5.4 描述,设定 <var>F</var> 的 [[Get]] 内部属性。
- 依照 13.2.1 描述,设定 <var>F</var> 的 [[Call]] 内部属性。
- 依照 13.2.2 描述,设定 <var>F</var> 的 [[Construct]] 内部属性。
- 依照 15.3.5.3 描述,设定 <var>F</var> 的 [[HasInstance]] 内部属性。
- 设定 <var>F</var> 的 [[Scope]] 内部属性为 <var>Scope</var> 的值。
- 令 <var>names</var> 为一个列表容器,其中元素是以从左到右的文本顺序对应 的标识符的字符串。
- 设定 <var>F</var> 的 [[FormalParameters]] 内部属性为 <var>names</var>。
- 设定 <var>F</var> 的 [[Code]] 内部属性为 。
- 设定 <var>F</var> 的 [[Extensible]] 内部属性为 true。
- 令 <var>len</var> 为 指定的形式参数的个数。如果没有指定参数,则令 <var>len</var> 为 0。
- 以参数 "length"、属性描述符 {[[Value]]: <var>len</var>, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false}、false 调用 <var>F</var> 的 [[DefineOwnProperty]] 内部方法。
- 令 <var>proto</var> 为仿佛使用 new Object() 表达式创建新对象的结果,其中 Object 是标准内置构造器名。
- 以参数 "constructor"、属性描述符 {[[Value]]: <var>F</var>, { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true}、false 调用 <var>proto</var> 的 [[DefineOwnProperty]] 内部方法。
- 以参数 "prototype"、属性描述符 {[[Value]]: <var>proto</var>, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}、false 调用 <var>F</var> 的 [[DefineOwnProperty]] 内部方法。
- 如果 <var>Strict</var> 是 true,则
- 令 <var>thrower</var> 为 [[ThrowTypeError]] 函数对象(13.2.3)。
- 以参数 "caller"、属性描述符 {[[Get]]: <var>thrower</var>, [[Set]]: <var>thrower</var>, [[Enumerable]]: false, [[Configurable]]: false}、false 调用 <var>F</var> 的 [[DefineOwnProperty]] 内部方法。
- 以参数 "arguments"、属性描述符 {[[Get]]: <var>thrower</var>, [[Set]]: <var>thrower</var>, [[Enumerable]]: false, [[Configurable]]: false}、false 调用 <var>F</var> 的 [[DefineOwnProperty]] 内部方法。
- 返回 <var>F</var>。
当用一个 this 值、一个参数列表调用函数对象 <var>F</var> 的 [[Call]] 内部方法,采用以下步骤:
- 用 <var>F</var> 的 [[FormalParameters]] 内部属性值、参数列表 <var>args</var>、10.4.3 描述的 this 值来建立函数代码的一个新执行环境,令 <var>funcCtx</var> 为其结果。
- 令 <var>result</var> 为 (也就是 <var>F</var> 的 [[Code]] 内部属性)解释执行的结果。如果 F 没有 [[Code]] 内部属性或其值是空的 ,则 <var>result</var> 是 (normal, undefined, empty)。
- 退出 <var>funcCtx</var> 运行环境,恢复到之前的执行运行环境。
- 如果 <var>result</var>.type 是 throw 则抛出 <var>result</var>.value。
- 如果 <var>result</var>.type 是 return 则返回 <var>result</var>.value。
- 否则 <var>result</var>.type 必定是 normal。返回 undefined。
当以一个可能的空的参数列表调用函数对象 <var>F</var> 的 [[Construct]] 内部方法,采用以下步骤:
- 令 <var>obj</var> 为新创建的 ECMAScript 原生对象。
- 依照 8.12 设定 <var>obj</var> 的所有内部方法。
- 设定 <var>obj</var> 的 [[Class]] 内部属性为 "Object"。
- 设定 <var>obj</var> 的 [[Extensible]] 内部属性为 true。
- 令 <var>proto</var> 为以参数 "prototype" 调用 <var>F</var> 的 [[Get]] 内部属性的值。
- 如果 Type(<var>proto</var>) 是 Object,设定 <var>obj</var> 的 [[Prototype]] 内部属性为 <var>proto</var>。
- 如果 Type(<var>proto</var>) 不是 Object,设定 <var>obj</var> 的 [[Prototype]] 内部属性为 15.2.4 描述的标准内置的 Object 原型对象。
- 以 <var>obj</var> 为 this 值,调用 [[Construct]] 的参数列表为 <var>args</var>,调用 <var>F</var> 的 [[Call]] 内部属性,令 <var>result</var> 为调用结果。
- 如果 Type(<var>result</var>) 是 Object,则返回 <var>result</var>。
- 返回 <var>obj</var>。
[[ThrowTypeError]] 对象是个唯一的函数对象,如下只定义一次:
- 创建一个新 ECMAScript 原生对象,令 <var>F</var> 为此对象。
- 依照 8.12 设定 <var>F</var> 的所有内部属性。
- 设定 <var>F</var> 的 [[Class]] 内部属性为 "Function"。
- 设定 <var>F</var> 的 [[Prototype]] 内部属性为 15.3.3.1 指定的标准内置 Function 的原型对象。
- 依照 13.2.1 描述设定 <var>F</var> 的 [[Call]] 内部属性。
- 设定 <var>F</var> 的 [[Scope]] 内部属性为全局环境。
- 设定 <var>F</var> 的 [[FormalParameters]] 内部属性为一个空列表。
- 设定 <var>F</var> 的 [[Code]] 内部属性为一个 ,它无条件抛出一个 TypeError 异常,不做其他事情。
- 以参数 "length"、属性描述符 {[[Value]]: 0, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false}、false 调用 <var>F</var> 的 [[DefineOwnProperty]] 内部方法。
- 设定 <var>F</var> 的 [[Extensible]] 内部属性为 false。
- 令 [[ThrowTypeError]] 为 <var>F</var>。