This is a deprecated document. The document with all updated changes for this proposal has been merged and available as an unified document here.
This document attempts to integrate the public fields and private fields proposals into a single, coherent, orthogonal whole. See the explainer for an overview.
"constructor"
.
"#constructor"
.
These static rules have been modified to produce an delete
operator is applied to a private reference.
It is a Syntax Error if the derived
and
The last rule means that expressions such as delete (((foo)))
produce early errors because of recursive application of the first rule.
With parameters object and enumerable.
With parameter homeObject.
With parameter functionObject and
The abstract operation SetFunctionName requires a Function argument F, a String, Symbol, or name
property to F by performing the following steps:
name
own property."["
, description, and "]"
."name"
, PropertyDescriptor{[[Value]]: name, [[Writable]]: "name"
).\
"arguments"
, return With parameter className.
constructor(... args){ super (...args);}
using the syntactic grammar with the constructor( ){ }
using the syntactic grammar with the "derived"
."constructor"
, F).
The [[Construct]] internal method for an ECMAScript Function object F is
called with parameters argumentsList and newTarget. argumentsList is
a possibly empty
"base"
, then"%ObjectPrototype%"
)."base"
, then"base"
, return super
Keyworddelete
OperatorWhen a delete
operator occurs within delete
operator occurs within
The abstract operation CreateDynamicFunction is called with arguments constructor, newTarget, kind, and args. constructor is the constructor function that is performing this action, newTarget is the constructor that new
was initially applied to, kind is either "normal"
, "generator"
, or "async"
, and args is a
"normal"
, then"%FunctionPrototype%"
."generator"
, then"%Generator%"
."async"
."%AsyncFunctionPrototype%"
.","
(a comma), and nextArgString."generator"
, then"async"
, then"generator"
, then"prototype"
, PropertyDescriptor{[[Value]]: prototype, [[Writable]]: "normal"
, perform "prototype"
property."anonymous"
).A prototype
property is created for every non-async function created using CreateDynamicFunction to provide for the possibility that the function will be used as a constructor.
The abstract operation PerformEval with arguments x, evalRealm, strictCaller, and direct performs the following steps:
"derived"
, let inDerivedConstructor be eval
function.These static semantics are applied by
When the abstract operation EvalDeclarationInstantiation is called with arguments body, varEnv, lexEnv, privateEnv, and strict, the following steps are taken:
eval
will not create a global var declaration that would be shadowed by a global lexical declaration.The ModuleDeclarationEnvironmentSetup abstract operation is used by InnerModuleInstantiation to initialize the
This abstract operation performs the following steps:
"ambiguous"
, throw a "*"
, then"ambiguous"
, throw a When an
FunctionDeclarationInstantiation is performed as follows using arguments func and argumentsList. func is the function object for which the
"arguments"
is an element of parameterNames, then"arguments"
is an element of functionNames or if "arguments"
is an element of lexicalNames, then"arguments"
, "arguments"
, "arguments"
, ao)."arguments"
appended.Parameter
When a
BlockDeclarationInstantiation is performed as follows using arguments code and env. code is the Parse Node corresponding to the body of the block. env is the
"prototype"
, PropertyDescriptor{[[Value]]: prototype, [[Writable]]: "prototype"
, PropertyDescriptor{[[Value]]: prototype, [[Writable]]: "prototype"
, PropertyDescriptor{[[Value]]: prototype, [[Writable]]: "prototype"
, PropertyDescriptor{[[Value]]: prototype, [[Writable]]: With parameters object and optional parameter functionPrototype.
With parameters object and enumerable.
"get"
)."set"
)."prototype"
, PropertyDescriptor{[[Value]]: prototype, [[Writable]]: "prototype"
, PropertyDescriptor{[[Value]]: prototype, [[Writable]]: The Private Name specification type is used to describe a globally unique record which represents a private field. A Private Name may be installed on any ECMAScript object with the
Each Private Name holds the following information:
Field | Type | Description |
---|---|---|
[[Description]] |
|
The string value passed to |
The list of fields in Private Names is expanded by the private methods and accessor proposal which is closely following this one.
All ECMAScript objects have a new additional internal slot, [[PrivateFieldValues]], which is a
Private fields are designed to have semantics analogous to WeakMaps. However, the implied garbage collection semantics are weaker: If all the references to a WeakMap are inaccessible, but there is still a reference to a key which was in the WeakMap, one would expect the value to be eventually collected. However, Private Names specifically do not have this connotation: because the reference from the Private Name to the Value is in a
Private Names are a specification type here, not directly observable to ECMAScript code. However, in a decorator integration strawman, an object wrapping Private Names would be exposed to allow greater metaprogramming.
When the phrase newly created object appears in this specification, perfom the following steps on the resulting object obj:
With parameters baseValue and baseReference.
The Reference type is used to explain the behaviour of such operators as delete
, typeof
, the assignment operators, the super
keyword and other language features. For example, the left-hand operand of an assignment is expected to produce a reference.
A Reference is a resolved name or property binding. A Reference consists of three components, the base value, the referenced name, and the Boolean valued strict reference flag. The base value is either
A
The following abstract operations are used in this specification to access the components of references:
The following abstract operations are used in this specification to operate on references:
The object that may be created in step 5.a.ii is not accessible outside of the above abstract operation and the ordinary object [[Get]] internal method. An implementation might choose to avoid the actual creation of the object.
The object that may be created in step 6.a.ii is not accessible outside of the above algorithm and the ordinary object [[Set]] internal method. An implementation might choose to avoid the actual creation of that object.
Private identifiers follow typical lexical scoping logic. This section contains amended algorithms for managing the scope of private identifiers.
Component | Purpose |
---|---|
LexicalEnvironment |
Identifies the |
VariableEnvironment |
Identifies the |
PrivateEnvironment |
Identifies the |
"#"
.ECMAScript function objects have the additional internal slots listed in
Internal Slot | Type | Description |
---|---|---|
[[Environment]] |
|
The |
[[PrivateEnvironment]] |
|
The |
[[FormalParameters]] | Parse Node | The root parse node of the source text that defines the function's formal parameter list. |
[[FunctionKind]] | String |
Either "normal" , "classConstructor" , "generator" , or "async" .
|
[[ECMAScriptCode]] | Parse Node | The root parse node of the source text that defines the function's body. |
[[ConstructorKind]] | String |
Either "base" or "derived" .
|
[[Realm]] |
|
The |
[[ScriptOrModule]] |
|
The script or module in which the function was created. |
[[ThisMode]] | (lexical, strict, global) |
Defines how this references are interpreted within the formal parameters and code body of the function. this refers to the |
[[Strict]] | Boolean |
|
[[HomeObject]] | Object |
If the function uses super , this is the object whose [[GetPrototypeOf]] provides the object where super property lookups begin.
|
[[Fields]] |
|
If the function is a class with instancefield declarations, this is a list of records representing those fields and their initializers. |
The abstract operation FunctionInitialize requires the arguments: a function object F, kind which is one of (Normal, Method, Arrow), a parameter list Parse Node specified by ParameterList, a body Parse Node specified by Body, a
The abstract operation FunctionCreate requires the arguments: kind which is one of (Normal, Method, Arrow), a parameter list Parse Node specified by ParameterList, a body Parse Node specified by Body, a
"non-constructor"
."normal"
.The abstract operation GeneratorFunctionCreate requires the arguments: kind which is one of (Normal, Method), a parameter list Parse Node specified by ParameterList, a body Parse Node specified by Body, a
"generator"
).The abstract operation AsyncGeneratorFunctionCreate requires the arguments: kind which is one of (
"generator"
).The abstract operation AsyncFunctionCreate requires the arguments: kind which is one of (
"async"
).When the abstract operation PrepareForOrdinaryCall is called with function object F and
With parameters scope and privateScope.
"default"
).An anonymous export default
declaration, and its function code is therefore always
With parameters scope and privateScope.
"prototype"
, PropertyDescriptor{[[Value]]: prototype, [[Writable]]: "prototype"
, PropertyDescriptor{[[Value]]: prototype, [[Writable]]: "default"
).An anonymous export default
declaration, and its function code is therefore always
With parameters scope and privateScope.
"prototype"
, PropertyDescriptor{[[Value]]: prototype, [[Writable]]: "prototype"
, PropertyDescriptor{[[Value]]: prototype, [[Writable]]: "default"
).An anonymous export default
declaration.
With parameters scope and privateScope.
"default"
).Most ECMAScript statements and declarations must beare logically terminated with a semicolon. Such semicolons may always appear explicitly in the source text. For convenience, however, such semicolons may be omitted from the source text in certain situations. These situations are described by saying that semicolons are automatically inserted into the source code token stream in those situations.
In the following rules, “token” means the actual recognized lexical token determined using the current lexical
There are three basic rules of semicolon insertion:
When, as the source text is parsed from left to right, a token (called the offending token) is encountered that is not allowed by any production of the grammar, then a semicolon is automatically inserted before the offending token if one or more of the following conditions is true:
}
.
)
and the inserted semicolon would then be parsed as the terminating semicolon of a do-while statement (However, there is an additional overriding condition on the preceding rules: a semicolon is never inserted automatically if the semicolon would then be parsed as an empty statement or if that semicolon would become one of the two semicolons in the header of a for
statement (see
The following are the only restricted productions in the grammar:
The practical effect of these restricted productions is as follows:
++
or --
token is encountered where the parser would treat it as a postfix operator, and at least one ++
or --
token, then a semicolon is automatically inserted before the ++
or --
token.
continue
, break
, return
, throw
, or yield
token is encountered and a continue
, break
, return
, throw
, or yield
token.
The resulting practical advice to ECMAScript programmers is:
++
or --
operator should appear on the same line as its operand.
return
or throw
statement or an yield
expression should start on the same line as the return
, throw
, or yield
token.
break
or continue
statement should be on the same line as the break
or continue
token.
The source
{ 1 2 } 3
is not a valid sentence in the ECMAScript grammar, even with the automatic semicolon insertion rules. In contrast, the source
{ 1
2 } 3
is also not a valid ECMAScript sentence, but is transformed by automatic semicolon insertion into the following:
{ 1
;2 ;} 3;
which is a valid ECMAScript sentence.
The source
for (a; b
)
is not a valid ECMAScript sentence and is not altered by automatic semicolon insertion because the semicolon is needed for the header of a for
statement. Automatic semicolon insertion never inserts one of the two semicolons in the header of a for
statement.
The source
return
a + b
is transformed by automatic semicolon insertion into the following:
return;
a + b;
The expression a + b
is not treated as a value to be returned by the return
statement, because a return
.
The source
a = b
++c
is transformed by automatic semicolon insertion into the following:
a = b;
++c;
The token ++
is not treated as a postfix operator applying to the variable b
, because a b
and ++
.
The source
if (a > b)
else c = d
is not a valid ECMAScript sentence and is not altered by automatic semicolon insertion before the else
token, even though no production of the grammar applies at that point, because an automatically inserted semicolon would then be parsed as an empty statement.
The source
a = b + c
(d + e).print()
is not transformed by automatic semicolon insertion, because the parenthesized expression that begins the second line can be interpreted as an argument list for a function call:
a = b + c(d + e).print()
In the circumstance that an assignment statement must begin with a left parenthesis, it is a good idea for the programmer to provide an explicit semicolon at the end of the preceding statement rather than to rely on automatic semicolon insertion.
ECMAScript programs can be written in a style with very few semicolons, based on a heavy dependence on automatic semicolon insertion. However, as described above, semicolons are not inserted at every newline, and some of these cases which do not have an automatically inserted semicolon can be counter-intuitive or confusing.
As new syntactic features are added to ECMAScript, additional cases requiring explicit semicolons emerge over time. As such, consistently explicit semicolon use is recommended.
The term "automatic semicolon insertion hazard" refers, informally, to a place where a developer may expect a semicolon to be inserted, but according to the rules described above, it is not. The rest of this section describes a number of automatic semicolon insertion hazards in this version of ECMAScript.
In a
(
). Without a semicolon, the two lines together will be treated as a function call.[
). Without a semicolon, the two lines together will be treated as property access, rather than an array literal.`
). Without a semicolon, the two lines together will be interpreted as tagged template literal, with the previous expression as the function tag.+
or -
. Without a semicolon, the two lines together will be interpreted as a usage of the corresponding infix operator.At the top level of class bodies, the only significant case where semicolons are used is in field declarations. As a consequence of the rules above, at the end of a field declaration with an initializer expression, a semicolon is required if the following line begins with any of the following:
in
or instanceof
. Without a semicolon, those tokens will instead be interpreted as an operator.Additionally, the declaration of a field named get
, set
or static
, if it does not have an initializer, is not at the end of the class body, and is not followed by a non-static non-async generator method, requires a semicolon. Without a semicolon, these tokens will be treated as modifiers to the following class element declaration. Note that async
does not have this property, as async method declarations do not permit a newline between the async
token and the method name.
© 2021 Daniel Ehrenberg, Jeff Morrison, Kevin Smith, Kevin Gibbons
All Software contained in this document ("Software") is protected by copyright and is being made available under the "BSD License", included below. This Software may be subject to third party rights (rights from parties other than Ecma International), including patent rights, and no licenses under such third party rights are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT https://ecma-international.org/memento/codeofconduct.htm FOR INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.