String[indexer]をIE6,IE7でも使いたい!

このエントリの趣旨は、「Base64的な処理だったら最初から Array で用意すればいいのに…」 じゃなくて、「どーしても、ここは String[indexer] が使いたいんじゃー」 ってケースを想定して読んでください。ちょっと例が悪かったです。

近頃の JavaScript は、String[indexer] 構文を使うことで文字列の各要素に直接アクセスすることができます。

var str = "abc";

alert(str[1]); // "b"

ただし、IE6, IE7 では String[indexer] 構文は機能しません。
# IE8 以降ならOK, IE6, IE7 では "abc"[0] は undefined になる(構文エラーにはならない)

このような制限があるため、クロスブラウザJavaScript ライブラリでは、IE6/IE7 とその他のブラウザの処理を切り分けるか、遅くなることを覚悟の上で String.charAt() を使わなければなりませんでした。

めんどい
var str = "abc";

if (IE6 || IE7) {
    alert(str.charAt(1)); // "b"
} else {
    alert(str[1]); // "b"
}
おそい
var str = "abc";

alert(str.charAt(1)); // "b"

ぴこーん

  • String[indexer] はダメでも、Array[indexer] は使えるんだよね?
  • じゃあ、String.split("") しといて Array[indexer] で参照すればいいんだよね?
var base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

if (!"0"[0]) { // String[indexer] が使えないと true
  base64 = base64.split(""); // String.split("") で配列化
}

function base64char(index) {
    // 一見すると String[indexer] 構文でアクセスしてるように見えるけど、
    // 実際は、IE67以外なら String[indexer] を使い、IE67 なら Array[indexer] でアクセスする
    return base64[index];
}

文字列をBase64化する処理でやってみたところ、String.charAt() を使う従来の方法にくらべ、1.3 〜 2倍 ほど速くなるようです。

上手く使えば、コードもすっきり + 速くなるので一石二鳥ですね。

Array[indexer] を使うべきケースで、String[indexer]を無理やり使うと、かなり遅くなるようです。