ECMAScript仕様輪読会 #98
前回: ECMAScript仕様輪読会 #97
Cosenseの招待リンク: https://scrapbox.io/projects/esspec/invitations/85b96c9fa718ce5185e307196ed8fb53
connpass: https://esspec.connpass.com/
ES Spec Draft: https://tc39.es/ecma262/
multipage: https://tc39.es/ecma262/multipage/
X hashtag: #esspec
便利ツール
esspec-memo: https://tars0x9752.github.io/esspec-memo/esspec.html
Scrapbox Codeblock Generator: https://vzvu3k6k.github.io/scrapbox-codeblock/
TC39 Terminology: https://github.com/tc39/how-we-work/blob/main/terminology.md
esmeta playground: https://es-meta.github.io/playground/
時事ネタ
自己紹介 (近況報告)
syumai syumai.icon
X: https://x.com/__syumai GitHub: https://github.com/syumai
TSを書いて暮らしてます
最近作ってたプロダクトが出ました
ずっとSlack Appをやってます
Cloudflare Workers Tech Talks in Tokyo #7 やります 
https://workers-tech.connpass.com/event/387081/
iwatsurut
とくに、イベントもなく過ごしています。
igrep(山本悠滋)
https://github.com/igrep/
先々週は月曜日から風邪気味だったので休んだ。この勉強会(と、別の勉強会)のために毎週火曜日は仕事を他の曜日より早い18時に切り上げるようにしているが、結局先週火曜日は19:30まで働いてしまった
https://fortee.jp/2026fp-matsuri 関数型まつりCFP締め切り迫る(4/5終日まで)
maru。(まる)
https://x.com/sbleru
https://github.com/sbleru
主にTSで仕事してます。React, Node。
何やってたっけ、
突貫でコピーボタンつけてみたやつ
https://jssync.usareru.workers.dev/rooms/hoge
yebis0942.icon いい仕事だ
yebis0942(えびす)
https://github.com/yebis0942
GoとTypeScriptを書いて暮らしています
Codexの上限2倍タイムが今週で終わってしまうのでソワソワしている
桜を見れないまま雨が降ってしまったのもあってソワソワしている
移動のため前半はちょっと発声できないかも…ということでソワソワしています
Ryuto Kawazu (河住 龍人)
中学生からプログラミングを初め、Next.jsやSvelteKitなどでのフルスタックWeb開発をしている
現在は、Zigでhttp/1.1サーバーとルーター開発中
同時編集JavaScript Playground
https://jssync.usareru.workers.dev/rooms/esspec_a
https://jssync.usareru.workers.dev/rooms/esspec_b
前回のあらすじ
https://syumai.github.io/esspec/summaries/summary-97.html
今回のメモ
code:js
// Code
// NaN
{
const d = new Date(NaN);
console.log(d.toUTCString());
}
// +0F
{
const d = new Date();
d.setFullYear(+0);
console.log(d.toUTCString());
}
// -0F
{
const d = new Date();
d.setFullYear(-0);
console.log(d.toUTCString());
}
// yearが3桁のパターン
{
const d = new Date(100, 0, 2);
console.log(d.toUTCString());
}
// yearが4桁のパターン
{
const d = new Date(2026, 4, 28, 10, 00);
console.log(d.toUTCString());
}
// yearが5桁のパターン
{
const d = new Date(10000, 0, 2);
console.log(d.toUTCString());
}
// Output
Invalid Date
Fri, 31 Mar 0000 10:42:54 GMT
Fri, 31 Mar 0000 10:42:54 GMT
Fri, 01 Jan 0100 14:41:01 GMT
Thu, 28 May 2026 01:00:00 GMT
Sat, 01 Jan 10000 15:00:00 GMT
code:js
// Code
{
const d = new Date();
console.log(String(d));
}
{
// date + date
const d1 = new Date();
const d2 = new Date();
console.log(d1 + d2);
}
{
const f = Date.prototypeSymbol.toPrimitive;
console.log(f.name);
}
{
function myToPrimitive() { return 1; }
Date.prototypeSymbol.toPrimitive = myToPrimitive;
const d1 = new Date();
const d2 = new Date();
console.log(d1 + d2);
}
{
function myToPrimitive() { return 1; }
const desc = Object.getOwnPropertyDescriptor(Date.prototype, Symbol.toPrimitive);
Object.defineProperty(Date.prototype, Symbol.toPrimitive, {
...desc,
value: myToPrimitive,
})
const d1 = new Date();
const d2 = new Date();
console.log(d1 + d2);
}
// Output
Tue Mar 31 2026 20:30:34 GMT+0900 (日本標準時)
Tue Mar 31 2026 20:30:34 GMT+0900 (日本標準時)Tue Mar 31 2026 20:30:34 GMT+0900 (日本標準時)
Symbol.toPrimitive
Tue Mar 31 2026 20:30:34 GMT+0900 (日本標準時)Tue Mar 31 2026 20:30:34 GMT+0900 (日本標準時)
2
code:js
// Code
// constructor
{
const s = new String(1);
console.log(typeof s);
console.log(s);
}
// function
{
const s = String(1);
console.log(typeof s);
console.log(s);
}
// subclass
{
class S1 extends String {
}
console.log(new S1());
console.log(typeof new S1());
console.log(new S1(123) + 456);
class SInvalid extends String {
constructor() {
this.aaa = 1;
}
}
console.log(new SInvalid());
}
// Output
object
1
string
1
object
123456
ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor
code:js
// Code
// NewTarget undefined, non-Symbol
{
console.log(String(123));
}
// NewTarget undefined, Symbol
{
const s = Symbol('bbbb');
console.log(String(s));
}
// NewTarget non-undefined, non-Symbol
{
console.log(new String(123));
}
// Symbol.prototype.toString
{
console.log(Symbol.toPrimitive.toString());
}
{
console.log("" + Symbol.toPrimitive);
}
// NewTarget non-undefined, Symbol
{
const s = Symbol('bbbb');
console.log(new String(s));
}
// Output
123
Symbol(bbbb)
123
Symbol(Symbol.toPrimitive)
TypeError: Cannot convert a Symbol value to a string
code:js
// Code
/* String */
{
console.log(function (...rest) {}.length); // 0
console.log(String.fromCharCode.length); // 1
}
{
console.log(String.fromCharCode(97)); // "a"
// ToUint16でmodが取られた結果なので同じ
console.log(String.fromCharCode(Math.pow(2, 16) + 97)); // "a"
// => String.fromCharCodeは内部でToUint16を呼び、数値を丸めてしまう
}
{
console.log(String.fromCharCode(97.5)) // "a"
// console.log(String.fromCodePoint(97.5)) // throw error
// => String.fromCodePointは引数のバリデーションが厳しい
}
{
// 英語の文字列をfromCharCode, fromCodePoint両方で
console.log(String.fromCharCode(97, 98, 99));
console.log(String.fromCodePoint(97, 98, 99));
// 日本語の文字列をfromCharCode, fromCodePoint両方で
console.log(String.fromCharCode(0x65E5, 0x672C, 99));
console.log(String.fromCodePoint(0x65E5, 0x672C, 99));
}
{
// ホッケの例 (サロゲートペア)
console.log(String.fromCharCode(0x29E3D)); // 鸽 // 鸽という漢字は、現代日本語ではハトという意味を持ちますが...
console.log(String.fromCodePoint(0x29E3D)); // 𩸽
console.log(String.fromCharCode("𩸽".charCodeAt(0), "𩸽".charCodeAt(1)));
console.log(String.fromCharCode("𩸽".charCodeAt(0)));
console.log(String.fromCharCode("𩸽".charCodeAt(1)));
}
// Output
0
1
a
a
a
abc
abc
日本c
日本c
鸽
𩸽
𩸽
�
�