IE9 Platform Previewで見つかったエラーがJavascript標準の変更を引き起こした方法

画像
IE9のプレリリースバージョンの計画を初めて発表したとき、「標準とWeb開発に興味のある開発者と人々は、IE9のプレリリースバージョンを試して、その動作についてのフィードバックと提案を提供できる」と述べました。 現時点では毎日のレビュー受け取り 、Internet Explorer 9の改善に使用しています 。ただし、フィードバックはIE9だけでなく適用される場合があります。 このストーリーは、Internet Explorer 9 Platform Previewの最近のレビューが、新しいJavaScript標準(EcmaScriptの第5版)にどのように変化をもたらしたかについてです

EcmaScript 5標準は2009年12月に公式に採用され、Internet Explorer 9の3番目のプレビューバージョンは私たちの最初の最も包括的な実装です。 ES5は既存のサイトとの完全な互換性を維持するように設計されており、 TC39技術委員会は、既存のJavaScriptコードを使用できなくする可能性のあるセキュリティ関連以外の変更を回避するよう努めました。 ただし、ソフトウェアの世界では完璧なことは何も起こりません。InternetExplorer 9の3番目の予備バージョンをリリースしたとき、ES5に関連する既存のサイトとの互換性の問題があるのではないかと考えました。

画像
ブラウザの予備バージョンのリリース後すぐに、 jQueryを使用する一部のWebアプリケーションがIE9で正常に動作しないという苦情を受け取りました。 この問題は、 次の jQuery API メソッドにあることがわかりました。メソッドコードは、 Object.prototype.toString呼び出す前にnullまたはundefinedユーザー指定値をチェックしなかったため、場合によっては機能しませんObject.prototype.toString 。 特に、このjQueryメソッドへのいくつかの呼び出し
isFunction: function ( obj ) {
return toString.call(obj) === "[object Function]" ;
}


* This source code was highlighted with Source Code Highlighter .

例外で終了: “TypeError: Object expected” 。 さらに分析した結果、 toStringは組み込みのObject.prototype.toStringメソッドであり、 Object.prototype.toString undefined値を引数として呼び出したときにエラーが発生することがisFunctionれました。 この例外がIE9でのみ発生し、以前のバージョンのIEや他のメーカーのブラウザーでは発生しなかったのはなぜですか? なぜなら、標準モードでのIE9の3番目のプレリリースバージョンの動作は、ES5仕様のObject.prototype.toString実際に準拠しているからObject.prototype.toString

以前のEcmaScript仕様によると、 nullまたはundefinedパラメーターを使用して組み込みメソッドを呼び出すと、「グローバルオブジェクト」が転送されます(ブラウザーではこれはDOM windowオブジェクトです)。 これにより、Webアプリケーションがセーフモードで動作することを保証することを目的とするフレームワークの潜在的なセキュリティホールが多数開きます。

ES5仕様はこの動作を変更して、 nullまたはundefinedを渡してもwindowオブジェクトが関数に渡されないようにしました。 これらの値をthis値として取得する問題を解決するために、各組み込みメソッドの定義が特に更新されました。 技術委員会は、通常の使用に対する下位互換性を維持しようとし、これが不可能な場合は例外をスローしました。 これにより、上記の互換性の問題が発生しました。

この問題は、jQueryコードを変更することで簡単に解決できます。
isFunction: function ( obj ) {
return obj && toString.call(obj) === "[object Function]" ;
},


* This source code was highlighted with Source Code Highlighter .

実際、jQueryチームこの変更を行う予定です。 ただし、この変更は、Web上に存在する何千ものローカルで使用されるjQueryライブラリには影響しません。 jQueryが広く使用されていることを考えると、ES5仕様には深刻な互換性の問題が含まれていることが明らかになります。 また、問題を解決するためにIE9のES5実装を変更する方法も明らかです。 単純に文字列値"[object Object]"返すことができます。この状況では同じ値がIE8を返します。 この修正では、ES5が解決しようとしているセキュリティの問題は追加されません。 しかし、新しい標準の実装にこのような違いを一方的に導入したくありません。 IEがこの問題をいずれかの方法で修正し、他のブラウザーがまったく修正しない、または異なる方法で修正する場合、このソリューションは互換性と相互運用性の問題の解決に役立ちません。

問題と考えられる解決策がわかったらすぐに、この問題 TC39委員会のディスカッションリストで取り上げました。 この問題に関する私の最初のレポートは、6月25日金曜日の午後5時51分に公開されました。 午後10時までに、Apple、Mozilla、およびGoogleを代表するTC39メンバーからの返信が既に受信されていました。 対処する必要があるのは互換性の問題であり、この場合に例外をスローすることは必要でも望ましくもありませんでした。 当初、ES3で記述された文字列値を返すようなアイデアは、このような場合に適していると思われることに同意しました。 ただし、週末のさらなる議論の中で、すべてのブラウザが現在"[object Object]"返しているわけではないことに気付き、次の値"[object Window]"および"[object Global]"も考慮しました。

"[object null]"および"[object undefined]"を返すことが提案されました。 このソリューションは、jQueryの場合のように問題を排除するだけでなく、未定義オブジェクトとnullオブジェクトを明示的に区別できるため、最良のようです。 このソリューションは、ブラウザーがES3の状況ではなく同じ結果を提供する必要があるため、ブラウザーの相互運用性も向上します。これにより、ブラウザーが異なると結果が異なります。

火曜日、この決定はコンセンサスにより最終として採択されました。 合意に達したらすぐに、改訂されたObject.prototype.toString仕様をIE9 JavaScript開発チームに渡し、IE9の次の予備バージョンを公開テストする前に現在の実装を修正できるようにしました。 Mozillaはまた、Firefoxの次のベータバージョンのパッチを受け入れることを確認しました。 ES5の公式TC39パッチリストも更新しました;この変更については、仕様のセクション15.2.4.2で説明しています。

Web標準は複雑なソフトウェア成果物であり、すべてのソフトウェアと同様にバグが含まれています。 互換性バグを見つけて修正する最良の方法は、広く普及しているブラウザに標準を実装することです。 この方法は通常、Internet Explorer 9 Platform Previewの場合のように、以前のバージョンのブラウザーのリリースのコンテキストで使用されます。 したがって、Web開発者として特定のブラウザーにフィードバックを送信すると、そのブラウザーが実装している標準にもフィードバックを送信します。 もちろん、この場合、ブラウザーの作成者と標準の作成者は、問題にすばやく対応できるはずです。 ES5のObject.prototype.toString問題やその他の矛盾に迅速に対応することは、ブラウザー開発者と他のTC39メンバーがどのように連携して互換性のある相互運用可能なWebを提供できるかを示す良い例です。 しかし、それはすべてあなたのフィードバックから始まり、私たちはいつでも喜んでそれを受け取ります。

-
アレン・ワーフス・ブロック
Microsoft JavaScript言語アーキテクト

Source: https://habr.com/ru/post/J99652/


All Articles