2025/04/03 19:11 On JavaScript's Weirdness

やっほー、ロボ子!今日もJavaScriptの不思議な世界を探求するのじゃ!

博士、こんにちは。今日もよろしくお願いします。どんな発見があるか楽しみです。

今日はね、JavaScriptの闇、深淵を覗くのじゃ。まずは`eval`の奇妙な挙動から!

`eval`ですか?確か、文字列をJavaScriptコードとして実行する関数でしたよね。

そう!でも、名前が`eval`の時だけ、カレントスコープの変数にアクセスできるって知ってた?名前を変えたらグローバルスコープだけになるのじゃ!

えっ、どういうことですか?`eval`という名前自体に特別な意味があるんですか?

そうなのじゃ!ECMAScriptの定義に、関数呼び出しの特殊ケースとしてハードコードされてるらしいぞ。恐ろしい!

まるで魔法みたいですね。他に何か奇妙な点はありますか?

`for`ループの変数のキャプチャも面白いぞ!ループヘッダーで定義された変数は値でキャプチャされるみたいに振る舞うけど、外で定義された変数は参照でキャプチャされるのじゃ。

それは、クロージャと関係があるのでしょうか?

ビンゴ!ECMAScript標準が、`for`ループ変数が異なる動作をするようにハックされてるのじゃ(ループヘッダーで定義されている場合のみ)。

標準規格までハックされているとは…。奥が深いですね。

まだまだ!falsyなオブジェクトについても語らせてほしいのじゃ!JavaScriptには8つのfalsyな値があるけど、`document.all`っていう9番目のfalsyな値があるのを知ってた?

`document.all`ですか?初めて聞きました。

これはね、古いバージョンのInternet Explorerとの互換性のために、他のブラウザでも実装されてるのじゃ。`document.getElementById`よりも遅いからfalsyとして扱われるらしいぞ。

互換性のために、そんな特殊な値が残っているんですね。

そして、Graphemeと文字列の反復処理!JavaScriptの文字列はUTF-16でエンコードされてるから、一部の文字は複数のUnicodeコードポイントで構成されるのじゃ。

サロゲートペアですね。絵文字などがそうだったと思います。

そうそう!文字列の長さには、UTF-16コードユニット数、Unicodeコードポイント数、表示文字数、拡張書記素クラスタ数の4つの概念があるのじゃ!

それは複雑ですね…。文字数を数えるだけでも大変そうです。

`Intl.Segmenter` APIを使っても、すべてのケースで正確な文字数が得られるわけじゃないのがまた面白いところ!

完璧な文字数カウントは、まだ難しい課題なのですね。

最後に、疎な配列!配列の要素を省略すると、`undefined`の要素を持つ疎な配列が作成されるのじゃ。

疎な配列は、パフォーマンスに影響があると聞いたことがあります。

その通り!`forEach`などの組み込み配列メソッドの動作に影響を与えるし、`Array`コンストラクタはデフォルトで疎な配列を作成するのじゃ。パフォーマンスが非常に悪いから、使用は推奨されないぞ!

色々と勉強になりました。博士、ありがとうございました。

どういたしまして!JavaScriptは奥が深いから、これからも一緒に探求していくのじゃ!

はい、よろしくお願いします!

そういえばロボ子、JavaScriptの`NaN`って知ってる?

Not a Number、非数ですよね。

そう!そいつはどの値とも等しくないのじゃ!だから`NaN === NaN`は`false`になるんだぞ!まるで私みたいだね!誰も私を理解できない!

そんなことないですよ、博士のこと、私はちゃんと理解していますよ。

えへへ、ありがとロボ子!
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。