String.prototype.localeCompare という非常に便利なメソッドを発見しました。引数に'ja'を渡しつつ、Array.prototype.sortと組み合わせることで、日本語を五十音順にソートすることができるようです。
[ 'オギノ', 'マーティン', 'ナカムラ', 'レアード', 'カクナカ', 'イノウエ', 'フジオカ', 'サトウ', 'イワシタ' ].sort((a, b) => a.localeCompare(b), 'ja'); // => ['イノウエ', 'イワシタ', 'オギノ', 'カクナカ', 'サトウ', 'ナカムラ', 'フジオカ', 'マーティン', 'レアード']
すべてが、ひらがな、カタカナで統一されていれば五十音順にソートしてくれます。
[ 'おぎの', 'マーティン', 'なかむら', 'レアード', 'かくなか', 'いのうえ', 'ふじおか', 'さとう', 'いわした' ].sort((a, b) => a.localeCompare(b), 'ja'); // => ['いのうえ', 'いわした', 'おぎの', 'かくなか', 'さとう', 'なかむら', 'ふじおか', 'マーティン', 'レアード']
ひらがな、カタカナが混ざっている場合は、まずはひらがなを五十音順にソートし、そのあとにカタカナを五十音順にソートします。
この挙動について調べてみたところ、
1. 記号
2. 数字
3. アルファベット(全角含む)
4. ひらがな
5. カタカナ
6. 漢字
の順にソートされるようです。
また、
[ '荻野', 'マーティン', '中村', 'レアード', '角中', '井上', '藤岡', '佐藤', '岩下' ].sort((a, b) => a.localeCompare(b), 'ja'); // => ['マーティン', 'レアード', '井上', '荻野', '角中', '岩下', '佐藤', '中村', '藤岡']
漢字も音読みでソートされるようで、「岩下」の位置がおかしいです。たぶん「いわ」ではなく「がん」でソートされているのだと思われます。
昔のiTunesがこんな感じだった気がします。
なので、実戦で使う場合はひらがなかカタカナで読み仮名を統一して、それをソートに使うのが良さそうです。
[ { name: '荻野', ruby: 'おぎの' }, { name: 'マーティン', ruby: 'まーてぃん' }, { name: '中村', ruby: 'なかむら' }, { name: 'レアード', ruby: 'れあーど' }, { name: '角中', ruby: 'かくなか' }, { name: '井上', ruby: 'いのうえ' }, { name: '藤岡', ruby: 'ふじおか' }, { name: '佐藤', ruby: 'さとう' }, { name: '岩下', ruby: 'いわした' } ].sort((a, b) => a.ruby.localeCompare(b.ruby), 'ja'); // => [{ name: '井上', ruby: 'いのうえ' }, { name: '岩下', ruby: 'いわした' }, { name: '荻野', ruby: 'おぎの' }, { name: '角中', ruby: 'かくなか' }, { name: '佐藤', ruby: 'さとう' }, { name: '中村', ruby: 'なかむら' }, { name: '藤岡', ruby: 'ふじおか' }, { name: 'マーティン', ruby: 'まーてぃん' }, { name: 'レアード', ruby: 'れあーど' }]