12
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

IE8でうまく動かないJavaScript

Last updated at Posted at 2015-08-25

これまで色々と罠にハメられたことのメモ。
Windows版のIE9以降では動くけどIE8では動かないコード。

これまで遭遇した中でも、あんまり再現条件が限定的だったりするものや経緯が複雑だったものは省いています。

(2015/08/26 追記) いくつかの現象は IE8 が ECMAScript3 をベースに、IE9 以上が ECMAScript5 をベースに動作することが原因で発生する現象です。 それらについても追記しました。

グローバル変数を delete 演算子で削除しようとするとエラー

何でなのかわかりません。調べる気も起きませんでした……

window.hoge = 'abc';

// エラー
delete window.hoge; // このオブジェクトではサポートされていない操作です
// 代わりに↓で代用する
window.hoge = void 0; // void 0 は undefined のこと

ECMAScript3 の delete 演算子および Global オブジェクトについてこのような仕様の言及は無さそうです。
IE8 の Global オブジェクト(=window)には [[Delete]] メソッドが定義されていないということでしょうか。

DOMエレメントの存在しないプロパティを delete 演算子で削除しようとするとエラー

削除できるうちは大丈夫らしい。

var elem = document.getElementById('fooBar');

elem.foo = 'bar';

delete elem.foo; // true
delete elem.foo; // オブジェクトでサポートされていないプロパティまたはメソッドです。

delete 演算子の仕様的に説明がつかないような……

String オブジェクトに添え字アクセスすると undefined

やる方が悪い。が、IE9以降では動いてしまうのだ。
特に String.prototype にメソッドを拡張するときに thisString オブジェクトになってしまうので注意。
そもそも charAt メソッドを使用しましょう。

文字への配列のようなアクセス方法(上記のふたつめの方法)は、 ECMAScript 3 仕様には含まれていません。これらは JavaScript と ECMAScript 5 の機能です。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String

var str = 'abc';
var strObj = new String(str);

// Stringオブジェクト+添え字を組み合わせると文字が取得できない
console.log(strObj[1]); // undefined
// charAt を使えば大丈夫
console.log(strObj.charAt(1)); // 'b'
// string型のプリミティブなら大丈夫
console.log(str[1]); // 'b'

// string型で扱いつつcharAtを使うのが最も無難
console.log(str.charAt(1)); // 'b'

// こんな風にメソッドを追加する場合、this が String オブジェクトにラップされているので注意が必要
String.prototype.lastChar = function() {
    return this[this.length - 1]; // IE8 だけ常に undefined が返る
};

添え字によるアクセスが出来ないこと自体は ECMAScript3 の仕様なので全部が全部 IE8 が悪いわけではないですが、以下の点で嫌らしいです。

  • string 型の値(String オブジェクトでないプリミティブ値)では添え字アクセスが可能
  • IE9以降だと動いてしまう(ECMAScript5 で仕様が見直された影響)

誰が悪いとかいう話ではないですが、気をつけた方がいいかと思います(特にインデックスアクセス可能な別言語に慣れている方はやらかしやすい模様です)。

parseInt'08', '09' を渡すと 0 にされる

8進数で解釈されるためです。'08', '09' は8進数として不正なため 0 にされます。
そもそも parseInt を使う意図がなければ私は Number 関数派です。

console.log(parseInt('07')); // 7
console.log(parseInt('08')); // 0

console.log(Number('07')); // 7
console.log(Number('08')); // 8

参考: 茨城県と栃木県のデータがおかしいときに確かめること

これは ECMAScript3 の仕様…と言いたいところですが、15.1.2.2 parseInt (string , radix) には以下の記載があるので残念だとは思います。

radix0 または undefined であり、 string の数が数字 0 で始まり xX も続かないとき、実装は、自由な判断で、数を 8 進数とも 10 進数とも解釈してよい。実装はこの場合、 10 進数として数を解釈することが推奨される。

innerHTML に改行コードを含む文字列を代入したあと取り出すと改行コードが消える

以下のコードは IE8 と IE9 以降で動きが違う。

var foo = document.getElementById('foo');
foo.innerHTML = 'hoge \r\n fuga';
console.log( foo.innerHTML ); // IE8では改行コードが消える

それに伴い、例えば jQuery で以下のコードの結果も変わる。

var text = 'hoge \r\n fuga';
console.log( $('#foo').text(text).html() ); // IE8 では \r\n が消える

…こんな仕様の違いに左右されるコードを書かないでよって気もしますが、某ライブラリがこういうことをしていて現象に遭遇したのと、過去にも同じ話に遭遇した記憶があるなぁと思ったのでメモ。

12
13
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?