Twitter hashtag: #esspec
便利ツール
自己紹介 (近況報告)
syumai
年末年始、例のアレ🦠で体調を崩して寝込んでました
ドラム、脚が動くようになりいい感じになってきました
スラムダンクを箱買いして読んでます
来週Serverless系のイベントで登壇します
Jun Yasumura / harupiyo Jun Yasumura.icon
CSSの知識をアップデート中
tars0x9752 (たーず / naoki aoyama) tars0x9752.icon
自分も年末年始体調崩して寝込んでいた
スノーボードシーズンインした
動画制作入門している
yebis0942yebis0942.icon
2023/1/17 所用あって1時間ほど遅刻しそうです。すみません…
noyannoyan.icon
dotfiles作りに目覚めました
冪等で宣言的な管理をするために試行錯誤
前回のあらすじ
今回の範囲
Runtime Semantics: ClassDefinitionEvaluation のステップ実行 (8) の続きから
code:js
// class A と B
class A {
x = 1;
constructor() {
this.p = 1;
}
hello() {
return "hello";
}
}
class B extends A {
x = 2;
}
classEnv → env をもとに作られた declarative environment record
Declarative Environment Record
classEnv
code:javascript
"CreateImmutableBinding" -> clo<DeclarativeEnvironmentRecord.CreateImmutableBinding>
"CreateMutableBinding" -> clo<DeclarativeEnvironmentRecord.CreateMutableBinding>
"DeleteBinding" -> clo<DeclarativeEnvironmentRecord.DeleteBinding>
"GetBindingValue" -> clo<DeclarativeEnvironmentRecord.GetBindingValue>
"HasBinding" -> clo<DeclarativeEnvironmentRecord.HasBinding>
"HasSuperBinding" -> clo<DeclarativeEnvironmentRecord.HasSuperBinding>
"HasThisBinding" -> clo<DeclarativeEnvironmentRecord.HasThisBinding>
"InitializeBinding" -> clo<DeclarativeEnvironmentRecord.InitializeBinding>
"SetMutableBinding" -> clo<DeclarativeEnvironmentRecord.SetMutableBinding>
"WithBaseObject" -> clo<DeclarativeEnvironmentRecord.WithBaseObject>
}
submap
code:javascript
}
env
code:javascript
"CanDeclareGlobalFunction" -> clo<GlobalEnvironmentRecord.CanDeclareGlobalFunction>
"CanDeclareGlobalVar" -> clo<GlobalEnvironmentRecord.CanDeclareGlobalVar>
"CreateGlobalFunctionBinding" -> clo<GlobalEnvironmentRecord.CreateGlobalFunctionBinding>
"CreateGlobalVarBinding" -> clo<GlobalEnvironmentRecord.CreateGlobalVarBinding>
"CreateImmutableBinding" -> clo<GlobalEnvironmentRecord.CreateImmutableBinding>
"CreateMutableBinding" -> clo<GlobalEnvironmentRecord.CreateMutableBinding>
"DeclarativeRecord" -> #1378 "DeleteBinding" -> clo<GlobalEnvironmentRecord.DeleteBinding>
"GetBindingValue" -> clo<GlobalEnvironmentRecord.GetBindingValue>
"GetThisBinding" -> clo<GlobalEnvironmentRecord.GetThisBinding>
"GlobalThisValue" -> #1374 "HasBinding" -> clo<GlobalEnvironmentRecord.HasBinding>
"HasLexicalDeclaration" -> clo<GlobalEnvironmentRecord.HasLexicalDeclaration>
"HasRestrictedGlobalProperty" -> clo<GlobalEnvironmentRecord.HasRestrictedGlobalProperty>
"HasSuperBinding" -> clo<GlobalEnvironmentRecord.HasSuperBinding>
"HasThisBinding" -> clo<GlobalEnvironmentRecord.HasThisBinding>
"HasVarDeclaration" -> clo<GlobalEnvironmentRecord.HasVarDeclaration>
"InitializeBinding" -> clo<GlobalEnvironmentRecord.InitializeBinding>
"OuterEnv" -> null
"SetMutableBinding" -> clo<GlobalEnvironmentRecord.SetMutableBinding>
"WithBaseObject" -> clo<GlobalEnvironmentRecord.WithBaseObject>
}
ダメそうな例
code:javascript
class A extends A {
}
new A();
/*
class A extends A {
^
ReferenceError: Cannot access 'A' before initialization
*/
自身のclass名をextends出来ないようにするために、classEnvのEnvironment Recordを作って使用している
code:js
"DefineOwnProperty" -> clo<OrdinaryObject.DefineOwnProperty>
"Delete" -> clo<OrdinaryObject.Delete>
"Extensible" -> true
"Get" -> clo<OrdinaryObject.Get>
"GetOwnProperty" -> clo<OrdinaryObject.GetOwnProperty>
"GetPrototypeOf" -> clo<OrdinaryObject.GetPrototypeOf>
"HasProperty" -> clo<OrdinaryObject.HasProperty>
"IsExtensible" -> clo<OrdinaryObject.IsExtensible>
"OwnPropertyKeys" -> clo<OrdinaryObject.OwnPropertyKeys>
"PreventExtensions" -> clo<OrdinaryObject.PreventExtensions>
"PrivateElements" -> #1420 "Set" -> clo<OrdinaryObject.Set>
"SetPrototypeOf" -> clo<OrdinaryObject.SetPrototypeOf>
}
superclass
code:js
"Call" -> clo<ECMAScriptFunctionObject.Call>
"ClassFieldInitializerName" -> ~empty~
"Construct" -> clo<ECMAScriptFunctionObject.Construct>
"ConstructorKind" -> ~base~
"DefineOwnProperty" -> clo<OrdinaryObject.DefineOwnProperty>
"Delete" -> clo<OrdinaryObject.Delete>
"ECMAScriptCode" -> |FunctionBody|FF<0> "Extensible" -> true
"FormalParameters" -> |UniqueFormalParameters|FF<0> "Get" -> clo<OrdinaryObject.Get>
"GetOwnProperty" -> clo<OrdinaryObject.GetOwnProperty>
"GetPrototypeOf" -> clo<OrdinaryObject.GetPrototypeOf>
"HasProperty" -> clo<OrdinaryObject.HasProperty>
"IsClassConstructor" -> true
"IsExtensible" -> clo<OrdinaryObject.IsExtensible>
"OwnPropertyKeys" -> clo<OrdinaryObject.OwnPropertyKeys>
"PreventExtensions" -> clo<OrdinaryObject.PreventExtensions>
"PrivateElements" -> #1426 "PrivateEnvironment" -> #1412 "PrivateMethods" -> #1440 "ScriptOrModule" -> #1386 "Set" -> clo<OrdinaryObject.Set>
"SetPrototypeOf" -> clo<OrdinaryObject.SetPrototypeOf>
"SourceText" -> "class A { x = 1 ; constructor ( ) { this . p = 1 ; } hello ( ) { return "hello" ; } }"
"Strict" -> true
"ThisMode" -> ~strict~
}
NewTargetの動作
code:js
class A {
constructor() {
console.log("A", new.target);
}
}
new A();
class B extends A {
constructor() {
super(); // superがないと例外が発生する
console.log("B", new.target);
}
}
new B();
function F() {
console.log("F", new.target);
}
new F();
/*
*/
14. If constructor is empty, then
ClassBodyが存在しない場合にはデフォルトのコンストラクタを定義するという処理
RealmとかEnvironmentとかの用語らしい
次回はEnvironmentとかを読みましょう
15. Else,
ClassBodyが存在する場合の処理
Runtime Semantics: DefineMethod
MakeMethod
homeObject
どんなときにabrupt completionを起こすのか
code:js
function thrower() { throw "error" }
class A {
thrower()() {} // Step1 の Evaluation of ClassElementName で例外を起こす例 }
ClassElementNameにはComputedPropertyNameが使えるので、名前を決定するときに処理を実行できる
c. Perform MakeClassConstructor(F).
F.[[IsClassConstructor]] to trueをするだけ
d. Perform SetFunctionName(F, className).
Function F (コンストラクタ) のnameプロパティにclassNameをセットする
code:js
class A {}
const a = new A();
a.constuctor.name // => 'A'
[[InitialName]]とは?
SetFunctionNameの第3引数 (prefix) が使われるケース
code:js
obj = {
get v() { return "I'm a getter method." } // このときprefixはget
};
desc = Object.getOwnPropertyDescriptor(obj, "v");
console.log(desc.get.name); // "get v"
16. Perform MakeConstructor(F, false, proto).
Step 14に相当することをやっているのか?
IsConstructor と MakeClassConstructor
MakeClassConstructor(F)を実行してもIsConstructor(F)がtrueになるとは限らない
MakeClassConstructor(F): F.[[IsClassConstructor]] = trueを実行する
IsConstructor(F): Fが[[Construct]] internal methodを持っていればtrueを返す
今回のまとめと次回予告
クラス定義を読むのは大変だった
このまま読み続けるのはつらそうなので、クラス定義は一旦ここで終了
Environment Recordsとかを読んでいく