Twitter hashtag: #esspec
便利ツール
時事ネタ
自己紹介 (近況報告)
syumai syumai.icon
Go / TSを書いて暮らしてます
iwatsurut
とくに、イベントもなく過ごしています。
8/4 TinyGo のキーボード作成ハンズオンに参加します。
前回のあらすじ
FunctionDeclarationInstantiation全体の復習
今回の範囲
16 ECMAScript Language: Scripts and Modules
16.1.1 Static Semantics: Early Errors
Script : ScriptBody
LexicallyDeclaredNames
重複NG
LexicallyDeclaredNames内での重複がなくても、VarDeclaredNamesと重複するとNG
VarDeclaredNames
重複OK
ScriptBody : StatementList
superのルール
StatementList内に現れるsuperは、direct eval内のもの以外は、Syntax Error扱い
direct eval内のものは、19.2.1.1のStep 10で説明されている code:js
class A {}
class B extends A {
constructor() {
eval("super();"); // direct eval
}
}
new B(); // OK
class C extends A {
constructor() {
(0, eval)("super();"); // indirect eval
}
}
new C(); // SyntaxError: 'super' keyword unexpected here
new.target のルール
StatementList内に現れるnew.targetは、direct eval内のもの以外は、Syntax Error扱い
direct eval内のものは、19.2.1.1のStep 10で説明されている code:js
// Node.jsだとerrorにならない!
// ブラウザだとerrorになる
new.target;
// --- 以下、Node.jsでの実行
console.log(new.target); // undefined
eval("new.target;"); // 何も起きない
(function () {
new.target;
})(); // 何も起きない
(0, eval)("new.target;"); // SyntaxError: new.target expression is not allowed here
他のランタイムで試した様子
~/go/src/github.com/syumai/til/js/esspec62(main ✗) deno run e.js
A new release of Deno is available: 1.44.1 → 1.45.4 Run deno upgrade to install it.
error: Uncaught SyntaxError: new.target expression is not allowed here
new.target;
^
at <anonymous> (file:///Users/syumai/go/src/github.com/syumai/til/js/esspec62/e.js:1:5)
~/go/src/github.com/syumai/til/js/esspec62(main ✗) bun e.js
1 | new.target;
^
SyntaxError: new.target is only valid inside functions or static blocks.
at <parse> (/Users/syumai/go/src/github.com/syumai/til/js/esspec62/e.js:1:1)
Bun v1.1.8 (macOS arm64)
~/go/src/github.com/syumai/til/js/esspec62(main ✗) node e.js
~/go/src/github.com/syumai/til/js/esspec62(main ✗)
Node.js -> OK
Deno -> NG
Bun -> NG
Chrome -> NG
evalでも eval("new.target;"); はNG
───────┬──────────────────────────────────────────────────────────────────────────────────────
│ File: e2.js
───────┼──────────────────────────────────────────────────────────────────────────────────────
1 │ eval("new.target;");
2 │
───────┴──────────────────────────────────────────────────────────────────────────────────────
~/go/src/github.com/syumai/til/js/esspec62(main ✗) node e2.js
~/go/src/github.com/syumai/til/js/esspec62(main ✗) deno run e2.js
error: Uncaught (in promise) SyntaxError: new.target expression is not allowed here
eval("new.target;");
^
at file:///Users/syumai/go/src/github.com/syumai/til/js/esspec62/e2.js:1:1
~/go/src/github.com/syumai/til/js/esspec62(main ✗) bun e2.js
1 | eval("new.target;");
^
SyntaxError: new.target is only valid inside functions or static blocks.
at /Users/syumai/go/src/github.com/syumai/til/js/esspec62/e2.js:1:1
Bun v1.1.8 (macOS arm64)
Labelの重複
syntax errorになるはず
code:js
a: console.log(1);
a: console.log(2);
Node.js / Deno / Bunいずれもsyntax errorにならず (?)
UndefinedBreakTargetのパターン
break先のラベルの識別子が存在しなければsyntax error
code:js
outside: for (let i = 0; i < 3; i++) {
inside: for (let j = 0; j < 3; j++) {
console.log("inside: ", j);
if (j === 1) {
break somewhere; // syntax error
}
}
console.log("outside: ", i);
}
余談: switch内のbreakから外側のfor loopから離脱できる
code:js
outsideFor: for (let i = 0; i < 10; i++) {
switch(i%3) {
case 0:
console.log("zero");
break;
case 1:
console.log("one");
break;
case 2:
console.log("two");
break outsideFor; // 外側のfor loopから抜けられる
}
}
UndefinedContinueTargetのパターン
Breakと同様
code:js
outside: for (let i = 0; i < 3; i++) {
inside: for (let j = 0; j < 3; j++) {
console.log("inside: ", j);
if (j === 1) {
continue somewhere; // syntax error
}
}
console.log("outside: ", i);
}
Private identifierのパターン
無効な場所で使うとsyntax error
strict modeの復習
Directive Prologue
code:js
"a"; 'b'; ""; "use strict";
with({}) {} // syntax error -> strict modeになる
Script Records
4フィールドを持つ
[[Realm]]
[[ECMAScriptCode]]
[[LoadedModules]]
Script Recordも、ロードしたModule一覧を持つ
-> eval用の仕様?
[[HostDefined]]
ブラウザなどのホストが自由に使える領域