Public Class Fields是目前處于Stage 2的ECMAScript特性,用于便捷的為class
聲明字段(fields),例如:
class A {
a = 1;
static b=2;
constructor() {
this.a //1
}
}
A.b //2
new A;
其中症概,
(1)Public Class Fields的語法是a=1
幔荒,而不是a:1
。
(2)字段a
在constructor
的函數(shù)體執(zhí)行之前就已經(jīng)賦值為1
了邢锯。
我們?nèi)绾未_認(rèn)這兩點(diǎn)呢?
1. 規(guī)范
找到Public Class Fields規(guī)范:https://tc39.github.io/proposal-class-public-fields/
2. 語法
Public Class Fields引入新的產(chǎn)生式(productions)和靜態(tài)語義(static semantics)搀别,
語法方面丹擎,我們只看這個新的產(chǎn)生式:
PublicFieldDefinition :
PropertyName Initializer
非終結(jié)符(nonterminal symbols)PropertyName和Initializer來自ECMAScript? 2017 Language Specification:
PropertyName :
LiteralPropertyName
ComputedPropertyName
Initializer :
= AssignmentExpression
我們看到Initializer
中包含終結(jié)符(terminal symbols)“=
”,
因此歇父,符合規(guī)范的語法是a=1
蒂培,而不是a:1
。
關(guān)于Static Public Class Fields庶骄,詳見Class Definitions
語法:
3. 語義
為了確定是否在constructor
的函數(shù)體執(zhí)行之前毁渗,Public Class Fields已經(jīng)被賦值了。
可以參考Public Class Fields規(guī)范新增的Runtime Semantics / Dynamic Semantics单刁。
內(nèi)部函數(shù)[[Construct]] ( argumentsList, newTarget )
原意是為了說明灸异,把函數(shù)作為構(gòu)造函數(shù)來調(diào)用時發(fā)生的事情。在這里羔飞,可以用來表明調(diào)用class
的constructor
時發(fā)生了什么肺樟,此時F
就是constructor
函數(shù),argumentsList
就是constructor
的參數(shù)列表逻淌,newTarget
就是constructor
函數(shù)中的this
么伯。(可參考,ECMAScript? 2017 Language Specification: 9.2.2 [[Construct]] ( argumentsList, newTarget )卡儒。
Public Class Fields規(guī)范對[[Construct]] ( argumentsList, newTarget )
進(jìn)行了修改田柔,
增加了InitializePublicInstanceFields(thisArgument, F)
俐巴。
我們看到InitializePublicInstanceFields
在OrdinaryCallEvaluateBody
之前執(zhí)行,
其中硬爆,OrdinaryCallEvaluateBody做的事情就是求值class
的constructor
函數(shù)體欣舵。
下面我們分兩個步驟理解InitializePublicInstanceFields
做的事情:
(1)InitializePublicInstanceFields
這個內(nèi)部函數(shù)先從constructor
中讀取內(nèi)部屬性(internal slot)[[PublicFields]]
然后逐個對Public Class Fields求值,把結(jié)果保存成多個屬性desc
缀磕,然后設(shè)置給O
缘圈。
constructor
就是InitializePublicInstanceFields(thisArgument, F)
中的F
,
O
就是InitializePublicInstanceFields(thisArgument, F)
中的thisArgument
袜蚕。
上文中我們看到InitializePublicInstanceFields
在OrdinaryCallEvaluateBody
之前執(zhí)行糟把。
這說明,在求值class
的構(gòu)造函數(shù)constructor
的函數(shù)體之前牲剃,
this
(即thisArgument
)已經(jīng)被設(shè)置了Public Class Fields屬性(即desc
)遣疯。
因此,字段a
在constructor
的函數(shù)體執(zhí)行之前就已經(jīng)賦值為1
了颠黎。
(2)[[PublicFields]]
這個內(nèi)部屬性(internal slot)是在class
定義的時候生成的另锋。
Public Class Fields規(guī)范:2.1.3 Runtime Semantics: ClassDefinitionEvaluation
ClassPublicFields
內(nèi)部函數(shù)根據(jù)產(chǎn)生式(productions)得到一個語法上的ClassElement
列表(list
)。
ClassPublicFieldDefinitionEvaluation
會根據(jù)語法生成一個內(nèi)部的數(shù)據(jù)結(jié)構(gòu)Record
狭归。
ClassPublicFields
和ClassPublicFieldDefinitionEvaluation
的具體定義如下:
參考
Github: tc39/proposals
Public Class Fields
ECMAScript? 2017 Language Specification