[JavaScript General] JavaScript でサロゲートペアを考慮して文字数をカウントする

http://codepen.io/ 上で悩んだのでまとめておく。

ES5 ではこんな感じで。

const str = '𠮷野家で𩸽';
function strlenEs5(str) {
  return str.length - (str.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g) || []).length;
}
console.log('ES5', strlenEs5(str)); // 5

ES2015 Spread Operator を使うと短く書けるということだが、うまく数えないし書き直せない。

const str = '𠮷野家で𩸽';
console.log('length', str.length); // 7
console.log('count', [...str].length); // 1

文字を配列として受け取り扱うという事かなぁ。
ということでそれっぽいコードを書いてみた。

const str = '𠮷野家で𩸽';
function strlenEs2015(str) {
  let chars = [];
  for (let c of str) { chars.push(c); }
  return chars.length;
}
console.log('ES2015', strlenEs2015(str)); // 5

Array.from でいけるとか。
内部的に for of 文のようなことをしているとのこと。

const str = '𠮷野家で𩸽';
function strlen(str) {
  let ary = Array.from(str);
  return ary.length;
}
console.log(strlen(str)); // 5

で、[...str].length もローカルでトランスパイルしたら問題なかったというオチ。

See the Pen JavaScript Surrogate Pair by DriftwoodJP (@DriftwoodJP) on CodePen.

補遺