6

そのため、ECMAScript 5 には ECMAScript 3 との非互換性がいくつか導入されています。


多くの 記事が書かれており、ES5 の厳密モードthis === null || this === undefinedで可能であると述べています。

"use strict";
(function () {
    alert(this); // null
}).call(null);

しかし、標準 が実際に示唆しているのは、ES5 エンジンは非厳密モードでもこれを許可するということです。

15.3.4.3 ... thisArg 値がそのまま値として渡されthisます。これは第 3 版からの変更で、aundefinedまたはnullthisArg がグローバル オブジェクトに置き換えられ、ToObject が他のすべての値に適用され、その結果がthis値として渡されます。

現在、ES5 をこのように実際に実装しているブラウザは IE9 だけであり、これにより現在のスクリプトが機能しなくなる可能性があることが判明しています。偉大な。


ES5 仕様の付録 E には、他にも多数の非互換性がリストされています。

では、十分に試行された ES3 スクリプトが問題なく動作し続けることを確認する最善の方法は何でしょうか? ある種の自動テストスイート?すべて手動でテストする必要がありますか?

4

2 に答える 2

6

記録として、質問者の ES5 15.3.4.3 の解釈は正しくありません。ES5 での厳密ではない関数への呼び出しは、ES3 と同じように見えるはずです。グローバル オブジェクトは、null または undefined を this 値として呼び出される非厳密な関数に引き続き渡されます。

分析の欠けている部分は、10.4.3「関数コードの入力」です。

関数オブジェクトFthisArgが提供された呼び出し元、およびargumentsListが提供された呼び出し元に含まれる関数コードの実行コンテキストに制御が入ると、次の手順が実行されます。

  1. 関数コードが厳密なコードの場合は、ThisBinding をthisArgに設定します。
  2. thisArgnullまたはundefinedの場合は、ThisBinding をグローバル オブジェクトに設定します。
  3. ...

ES3 は、呼び出し元が null または未定義の this 値をグローバル オブジェクトに置き換える責任があることを指定しました。ES5 は、呼び出し先がその責任を負うことを指定します (厳密モード関数でない場合)。非厳密なコードの場合、これは目に見える違いではありません。仕様の変更は、呼び出し先が厳密な関数である場合にのみ違いがあります。

于 2012-02-17T20:14:19.823 に答える
4

自動化されたテスト スイートは確かに良い考えです。

現在、ES5 を実装する実装がますます増えているため、スクリプト/ライブラリ/アプリケーションのテスト スイートを新しいブラウザーで実行することは、互換性を確保するための良い方法です。

私はES5 互換性テーブルを持っており、いくつかのより一般的な実装のサポート レベルをリストしています。網羅的ではありませんが、全体的な方向性を示しています。最新の IE、WebKit、Chrome、および Firefox はすべて、非常に優れた ES5 サポートを備えています。完全な適合性テストのために、いつでも公式の ES5 テスト スイートを実行できます (便利なようにここでオンラインにしています)。

テスト スイートがない場合 (他にいくつかの理由で非常に役立つため、実際に存在するはずです)、新しい (ES5 準拠の) 実装の 1 つで script/library/application を実行し、何が機能し、何が失敗するかを確認できます。

別の方法として、Annex E を参照することもできますリストはかなり大きいように見えますが、見た目ほど悪くはないことに注意してください。ES5 の目標の 1 つは、ES3 からの移行を多かれ少なかれ痛みを伴わずに行い、より根本的な変更をオプトインの厳密モードの領域に移行することでした。

そのリストからの互換性の変更の多くは、見過ごされる可能性があります。たとえば、15.1.1 の変更では、 globalundefinedとが読み取り専用になりましたNaN正常なアプリケーションはこれらのグローバル プロパティを(間違いInfinityを除いて) 再割り当てしないことを考えると、この変更は「アプリ ブレーカー」ではなく、より快適な「エラー キャッチャー」です。

15.10.2.12 では、もう 1 つの無害な変更があり、空白文字クラス ( \s) が <BOM> ( U+FEFF) 文字にも一致するようになりました。現在の実装におけるすべての逸脱を考慮すると (ES3 に関しても)、この変更はほとんどのアプリケーションで見過ごされる可能性があります。

ただし、0 で始まる文字列を 8 進値として扱わないようにするなど、より危険な変更もあります。もう生成しないでください(一部の実装では、意図的にその動作に違反することを選択しましたが)。それでも、 2 番目の「基数」引数なしで依存することは、決して良い習慣ではありません。したがって、アプリケーションが常に基数を指定する場合、心配する必要はありません。parseIntparseInt('010')8parseInt

そのため、付録 E を参照し、新しい実装 (できれば複数の実装) でスクリプトをテストし、ベスト プラクティスに従ってください。これは、互換性を確保するための良い方法です。

于 2010-10-22T17:16:56.663 に答える