作 ▸
JavaScript escape()が非推奨らしいので自作
JavaScriptの escape()
は非推奨というか、将来的に無くなるから、今後は使わない方がいいみたいです。ブラウザによって実装が違いすぎるからみたいです。
しかし先程、たまたま欲しくて探してたコードをネットで見つけたと思ったら escape()
が使われていて、しかも encodeURI()
とか encodeURIComponent()
に書き換えたら動かなくなるやつでした。なので自力で escape()
を書いてみました。
Chrome 78.0.3904.97
現在のChromeの挙動とMDNの記載を元に、自分が理解した仕様は以下の通りです。
- 英数字はエスケープしない。
- 特殊文字
@*_+-./
はエスケープしない。 - 文字コードが 0xFF 以下なら
%xx
形式でエスケープする。 - 文字コードが 0xFF より上なら
%uxxxx
形式でエスケープする。 - エスケープ後の16進数は大文字にする。
移植した関数が以下になります。
function myescape(str){
return str.replace(/[^a-zA-Z0-9@*_+\-./]/g, function(m) {
const code = m.charCodeAt(0);
if (code <= 0xff) {
return '%' + ('00' + code.toString(16)).slice(-2).toUpperCase();
} else {
return '%u' + ('0000' + code.toString(16)).slice(-4).toUpperCase();
}
});
}
unescape()
は知りません。
テストコード
以下のテストは通ってます。
function myescape(str){
return str.replace(/[^a-zA-Z0-9@*_+\-./]/g, function(m) {
const code = m.charCodeAt(0);
if (code <= 0xff) {
return '%' + ('00' + code.toString(16)).slice(-2).toUpperCase();
} else {
return '%u' + ('0000' + code.toString(16)).slice(-4).toUpperCase();
}
});
}
function _a(str) {
const result = escape(str) === myescape(str);
if (result) {
console.log(str, '->', myescape(str));
} else {
console.log('expected:', escape(str), ', actual:', myescape(str));
}
return result;
}
console.assert(_a('abc123'));
console.assert(_a('äöü'));
console.assert(_a('ć'));
console.assert(_a('@*_+-./'));
console.assert(_a('!?\\あああ'));
console.assert(_a('あいうえお'));
console.assert(_a('/🍅🐤/'));
console.assert(_a('じゃsp9宇\r\nfjさ惣\n\ndだあお\tうあw'));
abc123 -> abc123
äöü -> %E4%F6%FC
ć -> %u0107
@*_+-./ -> @*_+-./
!?\あああ -> %21%3F%5C%u3042%u3042%u3042
あいうえお -> %u3042%u3044%u3046%u3048%u304A
/🍅🐤/ -> /%uD83C%uDF45%uD83D%uDC24/
じゃsp9宇
fjさ惣
dだあお うあw -> %u3058%u3083sp%uFF19%u5B87%0D%0Afj%u3055%u60E3%0A%0A%uFF44%u3060%u3042%u304A%09%u3046%u3042%uFF57