ECMAScript仕様輪読会 #99
前回: ECMAScript仕様輪読会 #98
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/
時事ネタ
https://qnighy.github.io/ts-syntax-spec/
https://github.com/qnighy/ts-syntax-spec
自己紹介 (近況報告)
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/
関数型まつりCFP出せた😌
https://fortee.jp/2026fp-matsuri/proposal/477e0574-83a4-490b-9d89-ada5178c72c6
珍しく抽選に当たった
https://x.com/lapras_inc/status/2042164622451745277
maru。(まる)
https://x.com/sbleru
https://github.com/sbleru
主にTSで仕事してます。React, Node。
PRマージあざますmm
耳だけ参加します
台湾の新幹線乗ってます
yebis0942(えびす)
https://github.com/yebis0942
GoとTypeScriptを書いて暮らしています
ぎりぎりで葉桜を楽しめた
OSS活動をサボっていたらGitHub Copilot Proの無料提供が終わってしまった
同時編集JavaScript Playground
前半
https://jssync.syumai.workers.dev/rooms/esspec_a
後半
https://jssync.syumai.workers.dev/rooms/esspec_b
前回のあらすじ
https://syumai.github.io/esspec/summaries/summary-98.html
今回のメモ
code:js
// ===== Code =====
{
const filePath = String.rawC:\Development\profile\new.html;
console.log(The file was uploaded from: ${filePath});
// 予想される結果: "The file was uploaded from: C:\Development\profile\new.html"
}
{
const filePath = C:\Development\profile\new.html;
console.log(The file was uploaded from: ${filePath});
// 予想される結果: "The file was uploaded from: C:\Development\profile\new.html"
}
// ===== Output =====
The file was uploaded from: C:\Development\profile\new.html
The file was uploaded from: C:Developmentprofile
ew.html
code:js
// ===== Code =====
const name = "Bob";
console.log(String.rawHi\n${name}!);
// 'Hi\\nBob!' です。置き換えが処理されます。
console.log(String.rawHi \${name}!);
// 'Hi \\${name}!' です。ドル記号がエスケープされます。補間は行われません。
// ===== Output =====
Hi\nBob!
Hi \${name}!
code:js
// ===== Code =====
{
function myRaw(template, ...subs) {
template2 = "d";
console.log(JSON.stringify({ template, subs }, null, 2));
console.log(JSON.stringify({ "template.raw": template.raw }, null, 2));
return String.raw(template, ...subs);
}
console.log(myRawa${1}b${2}c${3}\n);
}
// ===== Output =====
{
"template": [
"a",
"b",
"c",
"\n"
],
"subs": [
1,
2,
3
]
}
{
"template.raw": [
"a",
"b",
"c",
"\\n"
]
}
a1b2c3\n
code:js
// ===== Code =====
{
const s1 = String(1);
const s2 = String(1);
const s3 = new String(1);
const s4 = new String(1);
console.log(s1 === s2);
console.log(s3 === s4);
console.log(typeof s1);
console.log(typeof s3);
}
// ===== Output =====
true
false
string
object
code:js
// ===== Code =====
{
const s1 = String(1);
const s3 = new String(1);
console.log(s1.valueOf());
console.log(s3.valueOf());
console.log(String.prototype.valueOf()); // String.prototypeのStringDataは空文字
}
// ===== Output =====
1
1
// 空文字
22.1.3.1 String.prototype.atに、This method performs the following steps when called:が無い
code:js
// ===== Code =====
{
console.log("𩸽".at(0));
console.log("鱧".at(0));
}
{
const s = "あいうえお";
console.log(s.at(0));
console.log(s.at(4));
console.log(s.at(4.5));
console.log(s.at(-5));
console.log(s.at(-5.5));
console.log(s.at(-6));
console.log(s.at(5));
String.prototype.at.call(null);
}
// ===== Output =====
�
鱧
あ
お
お
あ
あ
undefined
undefined
TypeError: String.prototype.at called on null or undefined
code:js
// ===== Code =====
// charAt
{
console.log("---- charAt ----");
console.log("𩸽".charAt(0));
console.log("𩸽".charAt(1));
// 範囲外
console.log("𩸽".charAt(-1));
console.log("𩸽".charAt(2));
}
// charCodeAt
{
console.log("---- charCodeAt ----");
console.log("𩸽".charCodeAt(0));
console.log("𩸽".charCodeAt(1));
// 範囲外
console.log("𩸽".charCodeAt(-1));
console.log("𩸽".charCodeAt(2));
}
// codePointAt
{
console.log("----- codePointAt ----");
console.log("𩸽".codePointAt(0));
console.log("𩸽".codePointAt(1));
// 範囲外
console.log("𩸽".codePointAt(-1));
console.log("𩸽".codePointAt(2));
// 文字列に戻す
console.log(String.fromCodePoint("𩸽".codePointAt(0)));
console.log(String.fromCodePoint("𩸽".codePointAt(1)));
}
// ===== Output =====
---- charAt ----
�
�
---- charCodeAt ----
55399
56893
NaN
NaN
----- codePointAt ----
171581
56893
undefined
undefined
𩸽
�
code:js
// ===== Code =====
// charAt
{
console.log("---- charAt ----");
const obj = {
charAt: String.prototype.charAt, // object Object を文字列にしたやつの部分を返す
};
console.log(obj.charAt(0)); // [
console.log(obj.charAt(1)); // o
console.log(obj.charAt(2)); // b
}
// ===== Output =====
---- charAt ----
[
o
b
code:js
// ===== Code =====
{
const parts = [
"𩸽".charAt(0),
"𩸽".charAt(1),
"𩸽".charAt(0),
"𩸽".charAt(1),
];
console.log("".concat(...parts));
}
// ===== Output =====
𩸽𩸽
code:js
// ===== Code =====
{
const parts = "👨‍👩‍👧‍👦".split("");
console.log(parts);
console.log("".concat(...parts));
}
{
const parts = ..."👨‍👩‍👧‍👦";
console.log(parts);
console.log("".concat(...parts));
}
// ===== Output =====
�,�,‍,�,�,‍,�,�,‍,�,�
👨‍👩‍👧‍👦
👨,‍,👩,‍,👧,‍,👦
👨‍👩‍👧‍👦
code:js
// String.prototype.atにはintentionally genericというNOTEはないが、定義上はthisがstringでなくても動かすことはできる
const fakeStr = { length: 1, toString: () => "a" };
console.log(String.prototype.charAt.call(fakeStr, 0)); // a
console.log(String.prototype.at.call(fakeStr, 0)); // a
↑ 他の NOTE 2 の内容があってもよさそう