やあ、こんにちは。フロントエンドの海を渡る君へ。
今日は、JavaScriptという言語が抱える「ちょっと奇妙で、でも愛すべきクセ」についてお話ししようと思うんだ。
Web開発をしていると、ユーザーが入力した名前や検索キーワードを比較する場面ってよくあるよね。でも、「あれ?同じ文字を書いているはずなのに、なぜかプログラムが『違うよ』って言ってくる…」なんて経験、ないかな?
実はそれ、JavaScriptのせいというより、「Unicode(ユニコード)」という世界共通の文字のルールが、意外と自由奔放すぎるからなんだ。今日はその謎を解く鍵、「`normalize()`」という魔法のメソッドを一緒に学んでいこう。
—
1. 文字にも「見た目は同じでも中身が違う」ことがある?
まずは例え話をしよう。君がスーパーで「りんご」を買うとするよ。
でも、その「りんご」の包み方が2通りあると想像してみて。
1. セット版:「り」と「ん」と「ご」が、あらかじめ一つの箱に詰められた状態。
2. バラ版:「り」と「ん」と「ご」が、別々の袋に入っていて、あとからくっつけた状態。
見た目はどちらも「りんご」だよね。でも、中身の構造は全く違う。
コンピュータの世界でも、これと同じことが起きているんだ。
例えば「が」という文字。
- NFC(合成済み):「が」という一つの文字として登録されている。
- NFD(分解):「か」と「濁点(゛)」という2つのパーツが合体して「が」に見せている。
プログラムにとって、この2つは「別物」として扱われることがほとんどなんだ。だから、`’が’ === ‘が’` と書いても、`false`(間違い!)と言われてしまう。これが、僕たち開発者を悩ませる「文字化け」や「検索不一致」の正体なんだ。
—
2. 魔法のメソッド `normalize()` の出番
そんなとき、バラバラだったり、くっついていたりする文字を「ひとつのルール」に統一してくれるのが `String.prototype.normalize()` だ。
これは、いわば「整理整頓の魔法」。どんなに散らかった文字の並びでも、これを通せばピシッと整列してくれるんだよ。
早速コードを見てみよう
// 「が」を分解したもの(NFD)と、そのままの「が」(NFC)を用意
const decomposed = “か\u3099”; // 分解された「が」
const combined = “が”; // 普通の「が」
console.log(decomposed === combined); // 結果は false (ひどい!見た目は同じなのに!)
// ここで normalize() の登場!
// ‘NFC’ を指定すると、分解されていた文字を「合成済み」に統一してくれるよ
const normalizedDecomposed = decomposed.normalize(‘NFC’);
console.log(normalizedDecomposed === combined); // 結果は true (やったね!)
どの形式を使えばいいの?
`normalize()` にはいくつか種類があるけれど、迷ったらこれだけ覚えておけば大丈夫だよ。
- ‘NFC’:基本はこれ。Webの世界では一番スタンダードで、効率的だ。
- ‘NFKC’:もっと厳しく整頓したいとき用。全角の「1」と半角の「1」を同じものとして扱いたい場合など、検索機能を賢くしたいときに使うよ。
—
3. なぜこの「ひと手間」が大切なのか
「そんなの、最初から統一しておけばいいじゃないか」と思うかもしれない。でも、インターネットは世界中の人が、色々なOSやキーボードを使って書き込んでいる場所なんだ。
iPhoneから打たれた「濁点」と、Windowsから打たれた「濁点」が、実は内部的に違う形式であることは珍しくない。
君が作った検索機能やユーザー登録画面で、「正しく入力したのにエラーになる」という悲しい事故を防ぐために、この `normalize()` を挟んであげる。これは「どんなユーザーにも等しく優しいフロントエンド」を作るための、エンジニアとしてのちょっとした心遣いなんだ。
—
最後に:つまずいたって大丈夫
最初は「Unicode正規化」なんて言葉を聞くと身構えてしまうかもしれない。でも大丈夫。今日君が学んだのは、「見た目が同じなら、中身も揃えてあげよう」という、とてもシンプルな「整理整頓」の考え方だけだ。
もしまた、文字の比較で謎のバグに出会ったら、思い出してほしい。
「あ、これ、りんごの袋詰め問題かもしれないな」って。
そうやって一つずつ、現場の泥臭い課題を解決していく過程こそが、君を一流のエンジニアへ育ててくれるはずだよ。またいつでも相談してね。応援しているよ!

コメント