こんばんは。前回の書き庫 で、localStorageに空の値を入れるとIE8がクラッシュすると書きました。なので、空の値が入らないようなチェックを入れれば良いのですが、それだけだとナンなので、症状をもう少し追ってみました。
もう一度、(IE8が)クラッシュするコードを書いておきます。
function addItem(){
var key = document.getElementById("key").value;
var value = document.getElementById("value").value;
window.localStorage[key] = value; // valueが空白だとクラッシュ!
}
以下のように、直接空の値を入れる分には大丈夫でした。
function addItem(){
var key = document.getElementById("key").value;
var value = document.getElementById("value").value; // これは使用しない
window.localStorage[key] = ""; // 直接、空の値を入れる → これは大丈夫。
}
ほうほう。で、クラッシュするデモページのHTMLソースをよく見てみると、input[type=text]でvalueの値を指定していないですね。もしかしてこのせいかなぁ、と
<input type="text" id="value" value="" />
value=""を追加しましたが、やっぱりクラッシュします。input[type=text]の値がないときでも、 document.getElementById("value").value はちゃんと文字列として解釈されます(typeof value == "string")。デモページは、input[type=text]のvalue値を取得していますが、これはTEXTAREA要素であっても、やはり内容が空っぽの場合、IE8ではクラッシュを引き起こしました。
何でですかねぇ。試しに、強引に文字列ではないオブジェクトを入れてもクラッシュしません。
window.localStorage[key] = document.getElementById("value"); // これは [object] という文字列に変換される
確かに、文字列のstringだとブラウザが解釈しているのに、それが空っぽだとクラッシュするわけです。じゃ、以下はどうだろうか。
var empty = ""; // 空っぽの変数を用意する。
window.localStorage[key] = empty; // これはセーフ。クラッシュしない。
さすがにこれはオッケーです。じゃ以下はどうだろうか?
var val = document.getElementById("val").value; // これが空っぽとする
var empty = ""; // val もempty も空っぽの場合
alert(empty === val); // 厳密等価演算子は true を返す
window.localStorage[key] = val; // なのに、val だとクラッシュ!
とりあえず string と認識しているはずなのに、代入する段階以降で、別のクラッシュを引き起こす「何か」と解釈されるらしい。というわけで、とりあえず以下のようにすれば、IE8でのクラッシュを回避できることが分かった。でも、ナンだかすっきりしないですね
function addItem(){
var _key = document.getElementById("key").value;
var _val = document.getElementById("val").value;
window.localStorage[_key] = new String(_val); // new String()で明示してあげる
alert("localStorage."+_key+" の値は「"+localStorage[_key]+"」です。");
}
new String()でちゃんと文字列オブジェクトとして再評価してあげると良いらしい。というわけで、IE8でもクラッシュしないlocalStorageのデモページをリンクしておきます。
→http://p2b.jp/demo/localStorage2.html
ちなみに、上のコードでalert(typeof new String(_val)) は何となるでしょうか? これは、 もはやstring ではなくobjectとなります。文字列オブジェクトです。
DOM storage
Comments