Warning:
This wiki has been archived and is now read-only.
ES5/附录
Contents
附录 A 文法摘要
A.1 词法
SourceCharacter :: any Unicode code unit
InputElementDiv :: WhiteSpace LineTerminator Comment Token DivPunctuator
InputElementRegExp :: WhiteSpace LineTerminator Comment Token RegularExpressionLiteral
WhiteSpace :: <TAB> <VT> <FF> <SP> <NBSP> <BOM> <USP>
LineTerminator :: <LF> <CR> <LS> <PS>
LineTerminatorSequence :: <LF> <CR> [lookahead ∉ <LF> ] <LS> <PS> <CR><LF>
Comment :: MultiLineComment SingleLineComment
MultiLineComment :: /* MultiLineCommentCharsopt */
MultiLineCommentChars :: MultiLineNotAsteriskChar MultiLineCommentCharsopt * PostAsteriskCommentCharsopt
PostAsteriskCommentChars :: MultiLineNotForwardSlashorAsteriskChar MultiLineCommentCharsopt * PostAsteriskCommentCharsopt
MultiLineNotAsteriskChar :: SourceCharacter but not *
MultiLineNotForwardSlashorAsteriskChar :: SourceCharacter but not one of / or *
SingleLineComment :: // SingleLineCommentCharsopt
SingleLineCommentChars :: SingleLineCommentChar SingleLineCommentCharsopt
SingleLineCommentChar :: SourceCharacter but not LineTerminator
Token :: IdentifierName Punctuator NumericLiteral StringLiteral
Identifier :: IdentifierName but not ReservedWord
IdentifierName :: IdentifierStart IdentifierName IdentifierPart
IdentifierStart :: UnicodeLetter $ _ \ UnicodeEscapeSequence
IdentifierPart :: IdentifierStart UnicodeCombiningMark UnicodeDigit UnicodeConnectorPunctuation <ZWNJ> <ZWJ>
UnicodeLetter any character in the Unicode categories “Uppercase letter (Lu)”, “Lowercase letter (Ll)”, “Titlecase letter (Lt)”, “Modifier letter (Lm)”, “Other letter (Lo)”,or “Letter number (Nl)”.
UnicodeCombiningMark any character in the Unicode categories “Non-spacing mark (Mn)” or “Combining spacing mark (Mc)”
UnicodeDigit any character in the Unicode category “Decimal number (Nd)”
UnicodeConnectorPunctuation any character in the Unicode category “Connector punctuation (Pc)”
ReservedWord :: Keyword FutureReservedWord NullLiteral BooleanLiteral
Keyword :: one of break do instanceof typeof case else new var catch finally return void continue for switch while debugger function this with default if throw delete in try
FutureReservedWord :: one of class enum extends super const export import 在严格模式下还会考虑以下保留字 implements let private public interface package protected static yield
Punctuator :: one of { } ( ) [ ] . ; , < > <= > = == != === !== + - * % ++ -- << >> >>> & | ^ ! ~ && || ? : = += -= *= %= <<= >>= >>>= &= |= ^=
DivPunctuator ::one of / /=
Literal :: NullLiteral BooleanLiteral NumericLiteral StringLiteral RegularExpressionLiteral
NullLiteral :: null
BooleanLiteral :: true false
NumericLiteral :: DecimalLiteral HexIntegerLiteral
DecimalLiteral :: DecimalIntegerLiteral . DecimalDigitsopt ExponentPartopt . DecimalDigits ExponentPartopt DecimalIntegerLiteral ExponentPartopt
DecimalIntegerLiteral :: 0 NonZeroDigit DecimalDigitsopt
DecimalDigits :: DecimalDigit DecimalDigits DecimalDigit
DecimalDigit :: one of 0 1 2 3 4 5 6 7 8 9
NonZeroDigit :: one of 1 2 3 4 5 6 7 8 9
ExponentPart :: ExponentIndicator SignedInteger
ExponentIndicator :: one of e E
SignedInteger :: DecimalDigits + DecimalDigits - DecimalDigits
HexIntegerLiteral :: 0x HexDigit 0X HexDigit HexIntegerLiteral HexDigit
HexDigit :: one of 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F
StringLiteral :: "DoubleStringCharactersopt " 'SingleStringCharactersopt '
DoubleStringCharacters :: DoubleStringCharacter DoubleStringCharactersopt
SingleStringCharacters :: SingleStringCharacter SingleStringCharactersopt
DoubleStringCharacter :: SourceCharacter but not one of " or \ or LineTerminator \ EscapeSequence LineContinuation
SingleStringCharacter :: SourceCharacter but not one of ' or \ or LineTerminator \ EscapeSequence LineContinuation
LineContinuation :: \ LineTerminatorSequence
EscapeSequence :: CharacterEscapeSequence 0 [lookahead ∉ DecimalDigit] HexEscapeSequence UnicodeEscapeSequence
CharacterEscapeSequence :: SingleEscapeCharacter NonEscapeCharacter
SingleEscapeCharacter :: one of ' " \ b f n r t v
NonEscapeCharacter :: SourceCharacter but not one of EscapeCharacter or LineTerminator
EscapeCharacter :: SingleEscapeCharacter DecimalDigit x u
HexEscapeSequence :: x HexDigit HexDigit
UnicodeEscapeSequence :: u HexDigit HexDigit HexDigit HexDigit
RegularExpressionLiteral :: / RegularExpressionBody / RegularExpressionFlags
RegularExpressionBody :: RegularExpressionFirstChar RegularExpressionChars
RegularExpressionChars :: [empty] RegularExpressionChars RegularExpressionChar
RegularExpressionFirstChar :: RegularExpressionNonTerminator but not one of * or \ or / or [ RegularExpressionBackslashSequence RegularExpressionClass
RegularExpressionChar :: RegularExpressionNonTerminator but not \ or / or [ RegularExpressionBackslashSequence RegularExpressionClass
RegularExpressionBackslashSequence :: \ RegularExpressionNonTerminator
RegularExpressionNonTerminator :: SourceCharacter but not LineTerminator
RegularExpressionClass :: [ RegularExpressionClassChars ]
RegularExpressionClassChars :: [empty] RegularExpressionClassChars RegularExpressionClassChar
RegularExpressionClassChar :: RegularExpressionNonTerminator but not ] or \ RegularExpressionBackslashSequence
RegularExpressionFlags :: [empty] RegularExpressionFlags IdentifierPart
A.2 数字转换
StringNumericLiteral ::: StrWhiteSpaceopt StrWhiteSpaceopt StrNumericLiteral StrWhiteSpaceopt
StrWhiteSpace ::: StrWhiteSpaceChar StrWhiteSpaceopt
StrWhiteSpaceChar ::: WhiteSpace LineTerminator
StrNumericLiteral ::: StrDecimalLiteral HexIntegerLiteral
StrDecimalLiteral ::: StrUnsignedDecimalLiteral + StrUnsignedDecimalLiteral - StrUnsignedDecimalLiteral
StrUnsignedDecimalLiteral ::: Infinity DecimalDigits . DecimalDigitsopt ExponentPartopt . DecimalDigits ExponentPartopt DecimalDigits ExponentPartopt
DecimalDigits ::: DecimalDigit DecimalDigits DecimalDigit
DecimalDigit :::one of 0 1 2 3 4 5 6 7 8 9
ExponentPart ::: ExponentIndicator SignedInteger
ExponentIndicator :::one of e E
SignedInteger ::: DecimalDigits + DecimalDigits - DecimalDigits
HexIntegerLiteral ::: 0x HexDigit 0X HexDigit HexIntegerLiteral HexDigit
HexDigit :::one of 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F
A.3 表达式
PrimaryExpression : this Identifier Literal ArrayLiteral ObjectLiteral ( Expression )
ArrayLiteral : [ Elisionopt ] [ ElementList ] [ ElementList , Elisionopt ]
ElementList : Elisionopt AssignmentExpression ElementList , Elisionopt AssignmentExpression
Elision : , Elision ,
ObjectLiteral : { } { PropertyNameAndValueList } { PropertyNameAndValueList , }
PropertyNameAndValueList : PropertyAssignment PropertyNameAndValueList , PropertyAssignment
PropertyAssignment : PropertyName : AssignmentExpression get PropertyName() { FunctionBody } set PropertyName( PropertySetParameterList ) { FunctionBody }
PropertyName : IdentifierName StringLiteral NumericLiteral
PropertySetParameterList : Identifier
MemberExpression : PrimaryExpression FunctionExpression MemberExpression [ Expression ] MemberExpression . IdentifierName new MemberExpression Arguments
NewExpression : MemberExpression new NewExpression
CallExpression : MemberExpression Arguments CallExpression Arguments CallExpression [ Expression ] CallExpression . IdentifierName
Arguments : ( ) ( ArgumentList )
ArgumentList : AssignmentExpression ArgumentList , AssignmentExpression
LeftHandSideExpression : NewExpression CallExpression
PostfixExpression : LeftHandSideExpression LeftHandSideExpression [no LineTerminator here] ++ LeftHandSideExpression [no LineTerminator here] --
UnaryExpression : PostfixExpression delete UnaryExpression void UnaryExpression typeof UnaryExpression ++ UnaryExpression -- UnaryExpression + UnaryExpression - UnaryExpression ~ UnaryExpression ! UnaryExpression
MultiplicativeExpression : UnaryExpression MultiplicativeExpression * UnaryExpression MultiplicativeExpression / UnaryExpression MultiplicativeExpression % UnaryExpression
AdditiveExpression : MultiplicativeExpression AdditiveExpression + MultiplicativeExpression AdditiveExpression - MultiplicativeExpression
ShiftExpression : AdditiveExpression ShiftExpression << AdditiveExpression ShiftExpression >> AdditiveExpression ShiftExpression >>> AdditiveExpression
RelationalExpression : ShiftExpression RelationalExpression < ShiftExpression RelationalExpression > ShiftExpression RelationalExpression <= ShiftExpression RelationalExpression >= ShiftExpression RelationalExpression instanceof ShiftExpression RelationalExpression in ShiftExpression
RelationalExpressionNoIn : ShiftExpression RelationalExpressionNoIn < ShiftExpression RelationalExpressionNoIn > ShiftExpression RelationalExpressionNoIn <= ShiftExpression RelationalExpressionNoIn >= ShiftExpression RelationalExpressionNoIn instanceof ShiftExpression
EqualityExpression : RelationalExpression EqualityExpression == RelationalExpression EqualityExpression != RelationalExpression EqualityExpression === RelationalExpression EqualityExpression !== RelationalExpression
EqualityExpressionNoIn : RelationalExpressionNoIn EqualityExpressionNoIn == RelationalExpressionNoIn EqualityExpressionNoIn != RelationalExpressionNoIn EqualityExpressionNoIn === RelationalExpressionNoIn EqualityExpressionNoIn !== RelationalExpressionNoIn
BitwiseANDExpression : EqualityExpression BitwiseANDExpression & EqualityExpression
BitwiseANDExpressionNoIn : EqualityExpressionNoIn BitwiseANDExpressionNoIn & EqualityExpressionNoIn
BitwiseXORExpression : BitwiseANDExpression BitwiseXORExpression ^ BitwiseANDExpression
BitwiseXORExpressionNoIn : BitwiseANDExpressionNoIn BitwiseXORExpressionNoIn ^ BitwiseANDExpressionNoIn
BitwiseORExpression : BitwiseXORExpression BitwiseORExpression | BitwiseXORExpression
BitwiseORExpressionNoIn : BitwiseXORExpressionNoIn BitwiseORExpressionNoIn | BitwiseXORExpressionNoIn
LogicalANDExpression : BitwiseORExpression LogicalANDExpression && BitwiseORExpression
LogicalANDExpressionNoIn : BitwiseORExpressionNoIn LogicalANDExpressionNoIn && BitwiseORExpressionNoIn
LogicalORExpression : LogicalANDExpression LogicalORExpression || LogicalANDExpression
LogicalORExpressionNoIn : LogicalANDExpressionNoIn LogicalORExpressionNoIn || LogicalANDExpressionNoIn
ConditionalExpression : LogicalORExpression LogicalORExpression ? AssignmentExpression : AssignmentExpression
ConditionalExpressionNoIn : LogicalORExpressionNoIn LogicalORExpressionNoIn ? AssignmentExpressionNoIn : AssignmentExpressionNoIn
AssignmentExpression : ConditionalExpression LeftHandSideExpression AssignmentOperator AssignmentExpression
AssignmentExpressionNoIn : ConditionalExpressionNoIn LeftHandSideExpression AssignmentOperator AssignmentExpressionNoIn
AssignmentOperator :one of = *= /= %= += -= <<= >>= >>>= &= ^= |= Expression : AssignmentExpression Expression , AssignmentExpression
ExpressionNoIn : AssignmentExpressionNoIn ExpressionNoIn , AssignmentExpressionNoIn
A.4 语句
Statement : Block VariableStatement EmptyStatement ExpressionStatement IfStatement IterationStatement ContinueStatement BreakStatement ReturnStatement WithStatement LabelledStatement SwitchStatement ThrowStatement TryStatement DebuggerStatement
Block : { StatementListopt }
StatementList : Statement StatementList Statement
VariableStatement : var VariableDeclarationList ;
VariableDeclarationList : VariableDeclaration VariableDeclarationList , VariableDeclaration
VariableDeclarationListNoIn : VariableDeclarationNoIn VariableDeclarationListNoIn , VariableDeclarationNoIn
VariableDeclaration : Identifier Initialiseropt
VariableDeclarationNoIn : Identifier InitialiserNoInopt
Initialiser : = AssignmentExpression
InitialiserNoIn : = AssignmentExpressionNoIn
EmptyStatement : ;
ExpressionStatement : [lookahead ∉ {{, function}] Expression ;
IfStatement : if ( Expression ) Statement else Statement if ( Expression ) Statement
IterationStatement : do Statement while ( Expression ); while ( Expression ) Statement for ( ExpressionNoInopt ; Expressionopt ; Expressionopt ) Statement for ( var VariableDeclarationListNoIn ; Expressionopt ; Expressionopt ) Statement for ( LeftHandSideExpression in Expression ) Statement for ( var VariableDeclarationNoIn in Expression ) Statement
ContinueStatement : continue [no LineTerminator here] Identifieropt ;
BreakStatement : break [no LineTerminator here] Identifieropt ;
ReturnStatement : return [no LineTerminator here] Expressionopt ;
WithStatement : with ( Expression ) Statement
SwitchStatement : switch ( Expression ) CaseBlock
CaseBlock : { CaseClausesopt } { CaseClausesoptDefaultClause CaseClausesopt }
CaseClauses : CaseClause CaseClauses CaseClause
CaseClause : case Expression : StatementListopt
DefaultClause : default : StatementListopt
LabelledStatement : Identifier : Statement
ThrowStatement : throw [no LineTerminator here] Expression ;
TryStatement : try Block Catch try Block Finally try Block Catch Finally
Catch : catch ( Identifier ) Block
Finally : finally Block
DebuggerStatement : debugger ;
A.5 函数和程序
FunctionDeclaration : function Identifier ( FormalParameterListopt ) { FunctionBody }
FunctionExpression : function Identifieropt ( FormalParameterListopt ) { FunctionBody }
FormalParameterList : Identifier FormalParameterList , Identifier
FunctionBody : SourceElementsopt
Program : SourceElementsopt
SourceElements : SourceElement SourceElements SourceElement
SourceElement : Statement FunctionDeclaration
A.6 统一资源定位符字符分类
uri ::: uriCharactersopt
uriCharacters ::: uriCharacter uriCharactersopt
uriCharacter ::: uriReserved uriUnescaped uriEscaped
uriReserved ::: one of ; / ? : @ & = + $ ,
uriUnescaped ::: uriAlpha DecimalDigit uriMark
uriEscaped ::: % HexDigit HexDigit
uriAlpha ::: one of a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
uriMark ::: one of - _ . ! ~ * ‘ ( )
A.7 正则表达式
Pattern :: Disjunction
Disjunction :: Alternative Alternative | Disjunction
Alternative :: [empty] Alternative Term
Term :: Assertion Atom Atom Quantifier
Assertion :: ^ $ \ b \ B ( ? = Disjunction ) ( ? ! Disjunction )
Quantifier :: QuantifierPrefix QuantifierPrefix ?
QuantifierPrefix :: * + ? { DecimalDigits } { DecimalDigits , } { DecimalDigits , DecimalDigits }
Atom :: PatternCharacter . \ AtomEscape CharacterClass ( Disjunction ) ( ? : Disjunction )
PatternCharacter :: SourceCharacter but not one of : ^ $ \ . * + ? ( ) [ ] { } |
AtomEscape :: DecimalEscape CharacterEscape CharacterClassEscape
CharacterEscape :: ControlEscape c ControlLetter HexEscapeSequence UnicodeEscapeSequence IdentityEscape
ControlEscape :: one of f n r t v
ControlLetter :: one of a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
IdentityEscape :: SourceCharacter but not IdentifierPart <ZWJ> <ZWNJ>
DecimalEscape :: DecimalIntegerLiteral [lookahead ∉ DecimalDigit]
CharacterClassEscape ::one of d D s S w W
CharacterClass :: [ [lookahead ∉ {^}] ClassRanges ] [ ^ ClassRanges ]
ClassRanges :: [empty] NonemptyClassRanges
NonemptyClassRanges :: ClassAtom ClassAtom NonemptyClassRangesNoDash ClassAtom – ClassAtom ClassRanges
NonemptyClassRangesNoDash :: ClassAtom ClassAtomNoDash NonemptyClassRangesNoDash ClassAtomNoDash – ClassAtom ClassRanges
ClassAtom :: - ClassAtomNoDash
ClassAtomNoDash :: SourceCharacter but not one of \ or ] or - \ ClassEscape
ClassEscape :: DecimalEscape b CharacterEscape CharacterClassEscape
A.8 JSON
A.8.1 JSON 词法
JSONWhiteSpace :: <TAB> <CR> <LF> <SP>
JSONString :: " JSONStringCharactersopt "
JSONStringCharacters :: JSONStringCharacter JSONStringCharactersopt
JSONStringCharacter :: SourceCharacter but not one of " or \ or U+0000 or U+001F \ JSONEscapeSequence
JSONEscapeSequence :: JSONEscapeCharacter UnicodeEscapeSequence
JSONEscapeCharacter :: one of " / \ b f n r t
JSONNumber :: -opt DecimalIntegerLiteral JSONFractionopt ExponentPartopt
JSONFraction :: . DecimalDigits
JSONNullLiteral :: NullLiteral
JSONBooleanLiteral :: BooleanLiteral
A.8.2 JSON 句法
JSONText : JSONValue
JSONValue : JSONNullLiteral JSONBooleanLiteral JSONObject JSONArray JSONString JSONNumber
JSONObject : { } { JSONMemberList }
JSONMember : JSONString : JSONValue
JSONMemberList : JSONMember JSONMemberList , JSONMember
JSONArray : [ ] [ JSONElementList ]
JSONElementList : JSONValue JSONElementList , JSONValue
附录 B 兼容性
附加语法
ECMAScript 的过去版本中还包含了说明八进制直接量和八进制转义序列的额外语法、语义。在此版本中已将这些附加语法、语义移除。这个非规范性的附录给出与八进制直接量和八进制转义序列一致的语法、语义,以兼容某些较老的 ECMAScript 程序。
数字直接量
7.8.3 中的语法、语义可以做如下扩展,但在严格模式代码里不允许做这样的扩展。语法
NumericLiteral :: DecimalLiteral HexIntegerLiteral OctalIntegerLiteral
OctalIntegerLiteral :: 0 OctalDigit OctalIntegerLiteral OctalDigit
OctalDigit :: one of 0 1 2 3 4 5 6 7
语义
- NumericLiteral :: OctalIntegerLiteral 的数学值是 OctalIntegerLiteral 的数学值。
- OctalDigit :: 0 的数学值是 0。
- OctalDigit :: 1 的数学值是 1。
- OctalDigit :: 2 的数学值是 2。
- OctalDigit :: 3 的数学值是 3。
- OctalDigit :: 4 的数学值是 4。
- OctalDigit :: 5 的数学值是 5。
- OctalDigit :: 6 的数学值是 6。
- OctalDigit :: 7 的数学值是 7。
- OctalIntegerLiteral :: 0 OctalDigit 的数学值是 OctalDigit 的数学值。
- OctalIntegerLiteral :: OctalIntegerLiteral OctalDigit 的数学值是 OctalIntegerLiteral 的数学值乘以 8 再加上 OctalDigit 的数学值。
字符串直接量
7.8.4 中的语法、语义可以做如下扩展,但在严格模式代码里不允许做这样的扩展。
语法
EscapeSequence :: CharacterEscapeSequence OctalEscapeSequence HexEscapeSequence UnicodeEscapeSequence
OctalEscapeSequence :: OctalDigit [lookahead ∉ DecimalDigit] ZeroToThree OctalDigit [lookahead ∉ DecimalDigit] FourToSeven OctalDigit ZeroToThree OctalDigit OctalDigit
ZeroToThree :: one of 0 1 2 3
FourToSeven :: one of 4 5 6 7
语义
- EscapeSequence :: OctalEscapeSequence 的字符值是 OctalEscapeSequence 的字符值。
- OctalEscapeSequence :: OctalDigit [lookahead ∉ DecimalDigit] 的字符值是个字符,它的 unicode 代码单元值是 OctalDigit 的数学值。
- OctalEscapeSequence :: ZeroToThree OctalDigit [lookahead ∉ DecimalDigit] 的字符值是个字符,它的 unicode 代码单元值是 ZeroToThree 的数学值乘以 8 再加上 OctalDigit 的数学值。
- OctalEscapeSequence :: FourToSeven OctalDigit 的字符值是个字符,它的 unicode 代码单元值是 FourToSeven 的数学值乘以 8 再加上 OctalDigit 的数学值。
- OctalEscapeSequence :: ZeroToThree OctalDigit OctalDigit 的字符值是个字符,它的 unicode 代码单元值是(ZeroToThree 的数学值乘以 82)加上(第一个 OctalDigit 的数学值乘以 8)加上 OctalDigit 的数学值。
- ZeroToThree :: 0 的数学值是 0。
- ZeroToThree :: 1 的数学值是 1。
- ZeroToThree :: 2 的数学值是 2。
- ZeroToThree :: 3 的数学值是 3。
- FourToSeven :: 4 的数学值是 4。
- FourToSeven :: 5 的数学值是 5。
- FourToSeven :: 6 的数学值是 6。
- FourToSeven :: 7 的数学值是 7。
附加属性
ECMAScript的某些实现给某些标准内置对象加入了额外属性。这个非规范性的附录为这些没有在本标准中提到的属性或它们的语义给出了一致的语义。
escape (string)
escape 函数是全局对象的一个属性。它通过将一些字符替换成十六进制转义序列,计算出一个新字符串值。
对于代码单元小于等于 0xFF 的被替换字符,使用 %xx 格式的两位数转义序列。对于代码单元大于 0xFF 的被替换字符,使用 %uxxxx 格式的四位数转义序列。
用一个参数 string 调用 escape 函数,采用以下步骤:
- 调用 ToString(string)。
- 计算 Result(1) 的字符数。
- 令 R 为空字符串。
- 令 k 为 0。
- 如果 k 等于 Result(2), 返回 R。
- 获得 Result(1) 中 k 位置的字符(表示为16位无符号整数)。
- 如果 Result(6) 是69个非空字符 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@*_+-./" 之一,则转到 步骤13。
- 如果 Result(6) 小于 256,则转到 步骤11。
- 令 S 为包含六个字符 "%u wxyz" 的字符串,其中 wxyz 是用四个十六进制数字编码的 Result(6) 值。
- 转到 步骤14。
- 令 S 为包含三个字符 "% xy" 的字符串,其中 xy 是用两个十六进制数字编码的 Result(6) 值。
- 转到 步骤14。
- 令 S 为包含单个字符 Result(6) 的字符串。
- 令 R 为将之前的 R 和 S 值连起来组成的新字符串。
- k 递增 1。
- 转到 步骤5。
unescape (string)
unescape 函数是全局对象的一个属性。它通过将每个可能是 escape 函数导入的转义序列,分别替换成代表这些转义序列的字符, 计算出一个新字符串值。
用一个参数 string 调用 unescape 函数,采用以下步骤:
- 调用 ToString(string)。
- 计算 Result(1) 的字符数。
- 令 R 为空字符串。
- 令 k 为 0。
- 如果 k 等于 Result(2),返回 R。
- 令 c 为 Result(1) 中 k 位置的字符。
- 如果 c 不是 % ,转到 步骤18。
- 如果 k 大于 Result(2) - 6,转到 步骤14。
- 如果 Result(1) 中 k + 1 位置的字符不是 u,转到 步骤14。
- 如果 Result(1) 中分别在 k + 2、k + 3、k + 4、k + 5 位置的四个字符不全是十六进制数字,转到 步骤14。
- 令 c 为一个字符,它的代码单元值是 Result(1) 中 k + 2、k + 3、k + 4、k + 5 位置的四个十六进制数字代表的整数。
- k 递增 5。
- 转到 步骤18。
- 如果 k 大于 Result(2) - 3,转到 步骤18。
- 如果 Result(1) 中分别在 k + 1、k + 2 位置的两个字符不都是十六进制数字,转到 步骤18。
- 令 c 为一个字符,它的代码单元值是两个零加上 Result(1) 中 k + 1、k + 2 位置的两个十六进制数字代表的整数。
- k 递增 2。
- 令 R 为将之前的 R 和 c 值连起来组成的新字符串。
- k 递增 1。
- 转到 步骤5。
String.prototype.substr (start, length)
substr 方法有两个参数 start 和 length,将 this 对象转换为一个字符串,并返回这个字符串中从 start 位置一直到 length 位置(或如果 length 是 undefined,就一直到字符串结束位置)的字符组成的子串。如果 start 是负数,那么它就被当作是 (sourceLength + start),这里的 sourceLength 是字符串的长度。返回结果是一个字符串值,不是 String 对象。采用以下步骤:
- 将 this 值作为参数调用 ToString。
- 调用 ToInteger(start)。
- 如果 length 是 undefined,就用 +∞;否则调用 ToInteger(length)。
- 计算 Result(1) 的字符数。
- 如果 Result(2) 是正数或零,就用 Result(2);否则使用 max(Result(4) + Result(2), 0)。
- 计算 min(max(Result(3), 0), Result(4) - Result(5))。
- 如果 Result(6) ≤ 0, 返回空字符串 "" 。
- 返回一个由 Result(1) 中的 Result(5) 位置的字符开始的连续的 Result(6) 个字符组成的字符串。
substr 方法的 length 属性是 2。
Date.prototype.getYear ( )
无参数方式调用 getYear 方法,采用以下步骤:
- 令 t 为 this时间值。
- 如果 t 是 NaN,返回 NaN。
- 返回 YearFromTime(LocalTime(t)) - 1900。
Date.prototype.setYear (year)
用一个参数 year 调用 setYear 方法,采用以下步骤:
- 令 t 为 LocalTime(this时间值) 的结果;但如果 this时间值 是 NaN,那么令 t 为 +0。
- 调用 ToNumber(year)。
- 如果 Result(2) 是 NaN,将 this 值的 [[PrimitiveValue]] 内部属性设为 NaN,并返回 NaN。
- 如果 Result(2) 不是 NaN 并且 0 ≤ ToInteger(Result(2)) ≤ 99,则 Result(4) 是 ToInteger(Result(2)) + 1900。否则,Result(4) 是 Result(2)。
- 计算 MakeDay(Result(4), MonthFromTime(t), DateFromTime(t))。
- 计算 UTC(MakeDate(Result(5), TimeWithinDay(t)))。
- 将 this 值的 [[PrimitiveValue]] 内部属性设为 TimeClip(Result(6))。
- 返回 this 值的 [[PrimitiveValue]] 内部属性值。
Date.prototype.toGMTString ( )
Date.prototype.toGMTString 的初始值是与 Date.prototype.toUTCString 的初始值相同的函数对象。
附录 C ECMAScript 的严格模式
严格模式下的限制和异常
- 在严格模式下,"implements"、"interface"、"let"、"package"、"private"、"protected"、"public"、"static"、和 "yield" 这些标识符都属于 FutureReservedWord。
- 符合规范的实现中,当处理严格模式下的代码时,不应该像 B.1.1 中描述地那样将 OctalIntegerLiteral 扩展到 NumericLiteral 的语法中。
- 符合规范的实现中,当处理严格模式下的代码时,不应该像 B.1.2 中描述地那样将 OctalEscapeSequence 扩展到 EscapeSequence 的语法中。
- 对一个未定义的标识符或其他无法解析的引用赋值时不会在全局对象上创建属性。在严格模式下,出现一个简单的赋值时,其 LeftHandSideExpression 不能解析为一个无法解析的引用。如果是那样,将抛出一个 ReferenceError 异常。同时,LeftHandSideExpression 不该引用到一个特性为 { [[Writable]]: false } 的数据属性上,也不该引用到一个特性为 { [[Set]]: undefined } 的访问器属性上,还不该引用到一个 [[Extensible]] 内部属性值为 false 的不可扩对象上。这些情况同样会抛出一个 TypeError。
- eval 或 arguments 不能出现在赋值运算符或后缀表达式的 LeftHandSideExpression 中,也不能作为前自增运算符或前自减运算符的 UnaryExpression。
- 在严格模式下,如果 ObjectLiteral 中的任何同名数据属性定义超过一次,那么这就是一个语法错误(11.1.5)。
- 如果在严格模式下执行 this 相关的代码,而且 this 的值没有强制指向一个对象。如果 this 的值是 null 或者 undefined,那么 this 就不会被转换成全局对象并且静态值不会被转换成包装对象。在函数调用的操作中(包括 Function.prototype.apply 和 Function.prototype.call)传入的 this 值不会被强制将传入的 this 值指向一个对象。
- 在严格模式下,VariableDeclaration 或 VariableDeclarationNoIn 中的 Identifier 出现 eval 或 arguments 时,抛出一个 SyntaxError。
- 严格模式下的代码不应该含有 WithStatement,如果存在则抛出一个 SyntexError。
- 在严格模式下,使用 TryStatement 语句时,如果 Catch 产生式中的 Identifier 是 eval 或 arguments,则抛出一个 SyntexError。
- 在严格模式下,FunctionDeclaration 或 FunctionExpression 中的 FormalParameterList 里面包含 eval 或 arguments 标识符,则抛出一个 SyntexError。Error creating thumbnail: Unable to save thumbnail to destination
- 在严格模式下,函数的形参列表中不能含有两个或两个以上的同名参数。当试图使用 FunctionDeclaration、FunctionExpression 或 Function构造器 来创建一个这样的函数时将抛出一个 SyntexError。
- 浏览器具体实现不会在当前规范下进行扩展,这也意味着包括严格模式下函数的 caller 或其实例的 arguments 属性。严格模式下,ECMAScript代码不能创建或者修改函数上的这些属性。(10.6、13.2、15.3.4.5.3)
- 在严格模式下,使用 eval 或 arguments 标识符作为 FunctionDeclaration 或 FunctionExpression 或 FormalParameterList 的名字,都会导致 SyntexError。试图使用 Function构造器 动态定义一个这样的严格模式函数也会抛出一个 SyntexError。
附录 D 第5版 中可能会对 第3版 产生兼容性影响的更正及澄清
全体:在 第3版 规范中像“就像用表达式 new Array() 一样”这样的短语的意思受到了误解。 第5版 规范中,对标准内置对象、属性的所有内部引用和内部调用相关文本描述,都做了澄清:应使用实际的内置对象,而不是对应命名属性的当前动态值。
11.8.2、11.8.3、11.8.5:ECMAScript 总体上是以从左到右的顺序解释执行,但是 第3版 规范中 > 和 <= 运算符的描述语言导致了局部从右到左的顺序。本规范已经更正了这些运算符,现在完全是从左到右的顺序解释执行。然而,这个对顺序的修改,如果在解释执行过程期间产生副作用,就有可能被观察到。
11.1.4:第5版 澄清了数组初始化结束位置的尾端逗号不计入数组长度。这不是对 第3版 语义的修改,但有些实现在之前可能对此有误解。
11.2.3:第5版 调换了算法 第2步 和 第3步 的顺序。第1版 一直到 第3版 规定的顺序是错误的,原来的顺序在解释执行 Arguments 时有副作用,可能影响到 MemberExpression 的解释执行结果。
12.14:在 第3版 中,对于传给 try语句 的 catch 子句的异常参数的名称解析,用与 new Object() 一样的方式创建一个对象来作为解析这个名称的作用域。如果实际的异常对象是个函数并且在 catch 子句中调用了它,那么作用域对象将会作为 this 值传给这个调用。在函数体里可以给它的 this 值定义新属性,并且这些属性名将在函数返回之后在 catch 子句的作用域内变成可见的标识符绑定。在 第5版 中,如果把异常参数作为函数来调用,传入的 this 值是 undefined。
13:在 第3版 中,有 Identifier 的 FunctionExpression 产生式的算法,用与 new Object() 一样的方式创建一个对象并加入到作用域链中,用来提供函数名查找的作用域。标识符解析规则(第3版 里的 10.1.4)会作用在这样的对象上,如果需要,还会用对象的原型链来尝试解析标识符。这种方式使得 Object.prototype 的所有属性以标识符的形式在这个作用域里可见。实践中,大多数 第3版 的实现都没有实行这个语义。第5版 更改了这里的语义,用一个声明式环境记录项来绑定了函数名。
14:在 第3版 中,产生式 SourceElements : SourceElements SourceElement 的算法不像相同形式的 Block 对语句的结果值做正确的传递。这可导致 eval 函数解释执行一个 Program 文本时产生错误的结果。实践中,大多数 第3版 的实现都做了正确的传递,而不关心 第5版 规定了什么。
15.10.6:RegExp.prototype 现在是一个 RegExp 对象,而不是 Object 的一个实例。用 Object.prototype.toString 可看到它的 [[Class]] 内部属性值现在是 "RegExp",不是 "Object"。
附录 E 第5版 内容的增加与变化,介绍 第3版 不兼容问题
7.1:Unicode 格式控制字符在受到处理之前不再从 ECMAScript 源文本中剥离。在 第5版 中,如果这样一个字符在字符串字面量或者正则表达式字面量中出现,这个字符会被合并到字面量中,而在 第3版 里,这个字符不会被合并。
7.2:Unicode 字符 <BOM> 现在是作为空格使用,如果它出现在本该是一个标识符的位置的中间,则会产生一个语法错误,而在 第3版 里不会。
7.3:换行符以前是作为转义字符处理,而现在允许换行符被包含在字符串字面量标记中。这在 第3版 中会产生一个语法错误。
7.8.5:现在的正则表达式字面量在字面量解析执行的时候都会返回一个唯一的对象。这个改变可以被任意测试字面量值的对象标识符或者一些敏感的副作用的程序检测到。
7.8.5:第5版 要求从 RegularExpressionLiteral 转换到 RegExp 对象时可能的错误作为早期错误抛出。在 第5版 之前的实现允许延迟抛出 TypeError,直到真正执行到这个对象。
7.8.5:在 第5版 中,未转义的 "/" 字符可以作为 CharacterClass 存在于正则表达式字面量中。在 第3版 里,这样的字符是作为字面量的最后一个字符存在。
10.4.2:在 第5版 中,间接调用 eval 函数会将全局对象作为 eval代码 的变量环境和 词法环境。在 第3版 中,eval 函数的间接调用者的变量和词法环境是作为 eval代码 的环境使用。
15.4.4:在 第5版 中,所有 Array.prototype 下的方法都是通用的。在 第3版 中,toString 和 toLocaleString 方法不是通用的,如果被非 Array 实例调用时会抛出一个 TypeError 的异常。
10.6:在 第5版 中,arguments 对象与实际的参数符合,它的数组索引属性是可枚举的。在 第3版 中,这些属性是不可枚举的。
10.6:在 第5版 中,arguments 对象的 [[Class]] 内置属性值是“Arguments”。在 第3版 中,它是“Object”。当对 arguments 对象调用 toString 的时候
12.6.4:当 in 表达式执行一个 null 或者 undefined 时,for-in 语句不再抛出 TypeError。取而代之的是将其作为不包含可枚举属性的对象执行。
15:在 第5版 中,下面的新属性都是在第三种中已存在的内建对象中定义,Object.getPrototypeOf, Object.getOwnPropertyDescriptor, Object.getOwnPropertyNames, Object.create, Object.defineProperty, Object.defineProperties, Object.seal, Object.freeze, Object.preventExtensions, Object.isSealed, Object.isFrozen, Object.isExtensible, Object.keys, Function.prototype.bind, Array.prototype.indexOf, Array.prototype.lastIndexOf, Array.prototype.every, Array.prototype.some, Array.prototype.forEach, Array.prototype.map, Array.prototype.filter, Array.prototype.reduce, Array.prototype.reduceRight, String.prototype.trim, Date.now, Date.prototype.toISOString, Date.prototype.toJSON。
15:实现现在要求忽略内建方法中的额外参数,除非明确指定。在 第3版 中,并没有规定额外参数的处理方式,实现中明确允许抛出一个 TypeError 错误。
15.1.1:全局对象的值属性 NaN、Infinity 和 Undefined 改为只读属性。
15.1.2.1:实现不再允许约束非直接调用 eval 的方式。另外间接调用 eval 会使用全局对象作为变量环境,而不是使用调用者的变量环境作为变量环境。
15.1.2.2:parseInt 的规范不再允许实现将 0 开头的字符串作为8进制值。
15.3.4.3:在 第3版 中,如果传入 Function.prototype.apply 的第二个参数不是一个数组对象或者一个 arguments 对象,就会抛出一个 TypeError。在 第5版 中,参数也可以是任意类型的含有 length 属性的类数组对象。
15.3.4.3,15.3.4.4:在 第3版 中,在 Function.prototype.apply 或者 Function.prototype.call 中传入 undefined 或者 null 作为第一个参数会导致全局对象被作为一个个参数传入,间接导致目标函数的 this 会指向全局变量环境。如果第一个参数是一个原始值,在原始值上调用 ToObject 的结果会作为 this 的值。在 第5版 中,这些转换不会出现,目标函数的 this 会指向真实传入的参数。这个不同点一般情况下对已存在的遵循 ECMAScript 第3版 的代码来说不太明显,因为相应转换会在目标函数生效之前执行。然而,基于不同的实现,如果使用 apply 或者 call 调用函数时,这个不同点就会很明显。另外,用这个方法调用一个标准的内建函数,并使用 null 或者 undefined 作为参数时,很可能会导致 第5版 标准下的实现与 第3版 标准下的实现不同。特别是 第5版 中代表性地规定了需要将实际调用的传入的 this 值作为对象的内建函数,在传入 null 或者 undefined 作为 this 值时,会抛出一个 TypeError 异常。
15.3.5.2:在 第5版 中,函数实例的 prototype 属性是不可枚举的。在 第3版 中,是可以枚举的。
15.5.5.2:在 第5版 中,一个字符串对象的 [[PrimitiveValue]] 的单个字符可以作为字符串对象的数组索引属性访问。这些属性是不可泄也不可配置的,并会影响任意名字相同的继承属性。在 第3版 中,这些属性不会存在,ECMAScript 代码可以通过这些名字动态添加和移除可写的属性并访问以这些名字继承的属性。
15.9.4.2:Date.parse 方法现在不要求第一个参数首先作为 ISO 格式字符串解析。使用这个格式但是基于特定行为实现(包括未来的一些行为)或许会表现的不太一样。
15.10.2.12:在 第5版 中,\s 现在可以匹配 <BOM> 了。
15.10.4.1:在 第3版 中,由 RegExp 构造器创建的对象的 source 字符串的精确形式由实现定义。在 第5版 中,字符串必须符合确定的指定条件,因此会和 第3版 标准的实现的结果不一样。
15.10.6.4:在 第3版 中,RegExp.prototype.toString 的规则不需要由 RegExp 对象的 source 属性决定。在 第5版 中,结果必须由 source 属性经由一个指定的规则,因此会和 第3版 实现的结果不一样。
15.11.2.1,15.11.4.3:在 第5版 中,如果一个错误对象的 message 属性原始值没有通过 Error 构造器指定,那么这个原始值就是一个空的字符串。在 第3版 中,这个原始值由实现决定。
15.11.4.4:在 第3版 中,Error.prototype.toString 的结果是由实现定义的。在 第5版 中,有完整的规范指定,因此可能会和 第3版 的实现不同。
15.12: 在 第5版 中,JSON 是在全局环境中定义的。 第3版 中,测试这个名词的存在会发现它是 undefined,除非这个程序或者实现定义了这个名词。
附录 F 5.1 版中技术上的重大更正和阐明
7.8.4:字符值定义追加了 DoubleStringCharacter :: LineContinuation 与 SingleStringCharacter :: LineContinuation。
10.2.1.1.3:参数 S 是不能被忽略的。它控制着试图设置一个不可改变的绑定时是否抛出异常。
10.2.1.2.2:在算法的 第5步,真被传递后最后一个参数为 [[DefineOwnProperty]]。
10.5:当重定义全局函数使,原算法 第5.5步 调整为现在的 第5.6步,并加入一个新的 第5.5步 用来还原与第三版的兼容性。
11.5.3:在最后符号项,指定使用 IEEE754 舍入到最接近模式。
12.6.3:在 第3.1.2步 的两种算法中修复缺失的 ToBoolean。
12.6.4:在最后两段的额外最后一句中,阐明某些属性枚举的规定。
12.7、12.8、12.9:BNF 的修改为阐明 continue 或 break 语句没有一个 Identifier 或一个 return 语句没有一个表达式时,在分号之前可以有一个 LineTerminator。
12.14:算法1 的 第3步,算法3 的 第2.1步 中,纠正这样的值 B 是作为参数传递而不是 B 本身。
15.1.2.2:在算法的 第2步 中阐明 S 可能是空字符串。
15.1.2.3:在算法的 第2步 中阐明 trimmedString 可以是空字符串。
15.1.3:添加注释阐明 ECMAScript 中的 URI 语法基于 RFC 2396 和较新的 RFC 3986。
15.2.3.7:在算法 第5步 和 第6步 中更正使用变量 P。
15.2.4.2:第5版 处理 undefined 和 null 值导致现有代码失败。规范修改为保持这样的代码的兼容性。在算法中加入新的 第1步 和 第2步。
15.3.4.3:第5版 中的 第5步 和 第7步 已被删除,因为它们规定要求 argArray 参数与泛数组状对象的其它用法不一致。
15.4.4.12:在 第9.1步,用 actualStart 替换不正确 relativeStart 引用。
15.4.4.15:阐明 fromIndex 的默认值是数组的长度减去 1。
15.4.4.18:在算法的 第9步,undefined 是现在指定的返回值。
15.4.4.22:在 第9.3.2步,第一个参数的 [[Call]] 内部方法已经改变为 undefined,保持与 Array.prototype.reduce 定义的一致性。
15.4.5.1:在算法 第3.12.2步 和 第3.12.3步 中,变量的名字是相反的,导致一个不正确的相反测试。
15.5.4.9:规范要求每有关规范等效字符串删除,算法从每一个段落都承接,因为它在 注2 中被列为建议的。
15.5.4.14:在 split 算法 第11.1步 和 第13.1步,SplitMatch 参数的位置顺序已修正为匹配 SplitMatch 的实际参数特征。在 第13.1.3.7.4步,lengthA 取代 A.length。
15.5.5.2:在首段中,删除的单个字符属性访问“array index”语义的含义。改进算法 第3步 和 第5步,这样它们不执行“array index”的要求。
15.9.1.15:为缺失字段指定了合法值范围。淘汰“time-only”格式。所有可选字段指定默认值。
15.10.2.2:算法步骤编号为 第2步 所产生的内部闭包被错误的编号,它们是额外的算法步骤。
15.10.2.6:在 第3步 中的列表中抽象运算符 IsWordChar 的第一个字符是“a”而不是“A”。
15.10.2.8:在闭包算法返回抽象运算符 CharacterSetMatcher 中,为了避免与一个闭包的形参名称冲突,第3步 中定义的变量作为参数传递在 第4步 更名为 ch。
15.10.6.2:第步9.5步 被删除,因为它执行了 I 的额外增量。
15.11.1.1:当 message 参数是 undefined 时,撤销 message 自身属性设置为空字符串的要求。
15.11.1.2:当 message 参数是 undefined 时,撤销 message 自身属性设置为空字符串的要求。
15.11.4.4:第6步 到 第10步 修改 / 添加正确处理缺少或空的 message 属性值。
15.12.3:在 JA 的内部操作的 第10.2.3步,串联的最后一个元素是 “]”。