2

新しい JavaScript アプリケーションを開始しており、厳格モードを使用したいと考えています。ただし、strict モードをサポートしていない一部の古いブラウザー (IE8、9) は引き続きサポートする必要があります。私の同僚の何人かは、strict モードに伴うランタイム セマンティクスの変更について心配しています。彼らは、古いブラウザで lax モードで実行すると、strict 関数が異なる動作をすることを懸念しています。

関数が lax モードで strict モードと同じランタイム セマンティクスを持つようにするために追加できる一連の追加の制限はありますか? 具体的には、自動化されたリントのようなツールでチェックできる一連のルールが必要です。私の最初の考えは、人々がevalorを使用できないようにすることargumentsです。それで十分でしょうか?

これを実現するために、coffeescript でのコーディングは役立ちますか?


たとえば、次の関数を考えてみましょう。

(function(){
 'use strict';

 function foo(bar) {
    arguments[0] = 'You are in lax mode';
    alert(bar);
 }
 foo('You are in strict mode');
 })();

この関数は、strict モードでは正しく動作しますが、lax モードでは動作が異なります。人々が誤ってこれを行うことがないようにする一連のルールを探しています。

4

3 に答える 3

3

すべての厳密モード機能は、ECMAScript 仕様のAnnex Cにまとめられています。ほとんどの場合、許可されていない機能 (新しい予約語、8 進リテラルとエスケープ シーケンス、オブジェクト リテラル内の同じプロパティの複数定義など) を使用しようとすると、strict モードはエラーをスローします。あなたの質問はエラーをスローしないケースに関するものだと理解していますので、以下に示します。

  • 厳密モード関数の Arguments オブジェクトは、その配列のインデックス付きプロパティ値を、それらの関数の対応する仮パラメーター バインディングと動的に共有しません。(10.6)。

  • 厳密モード関数の場合、arguments オブジェクトが作成された場合、arguments オブジェクトへのローカル識別子引数のバインディングは不変であるため、代入式のターゲットにならない場合があります。(10.5)。

これにより、例に見られる問題が発生します。の使用を完全に禁止している場合は、argumentsここで問題は発生しません。の使用を禁止するのargumentsは過激すぎると個人的には思いますが、それはあなたの判断です。

  • Strict モードの eval コードは、eval の呼び出し元の変数環境で変数または関数をインスタンス化できません。代わりに、新しい変数環境が作成され、その環境が eval コード (10.4.2) の宣言バインディングのインスタンス化に使用されます。

も許可evalしていないので、ここでも問題ありません。

thisが厳密モード コード内で評価される場合、this値はオブジェクトに強制されません。またはのthis値はグローバル オブジェクトに変換されず、プリミティブ値はラッパー オブジェクトに変換されません。関数呼び出し ( および を使用して行われた呼び出しを含む) を介して渡された値は、渡されたこの値をオブジェクト (10.4.3、11.1.1、15.3.4.3、15.3.4.4) に強制しません。nullundefinedthisFunction.prototype.applyFunction.prototype.call

これは次の 2 つのことを意味します。

  1. this未定義の場合、グローバルオブジェクトに強制されないため、次のようになります。

    //"use strict";
    function foo() {
        console.log(this); 
    }
    foo();
    // logs undefined in strict mode, and window in classic mode
    

    これは静的解析では捉えられないと思います。で何をしたいかによっては、厳密モードでエラーが発生する場合がありますthis。たとえば、関数内ではthis.foo = 'bar'、クラシック モードではグローバル変数が作成されますが、クラシック モードでは TypeError が発生します。ただしtypeof this、エラーはスローされず、異なる結果が得られるだけです。

  2. thisプリミティブ値として設定されている場合、ラッパー オブジェクトに強制されません。例えば:

    //"use strict";
    function valtype() { return typeof this }
    console.log(valtype.call("foo"));
    // logs "string" in strict mode and "object" in classic mode
    

    これは大したことではないように思えますが、問題を引き起こす可能性があります。これも静的解析では検出できないと思います。

結論: 制限を課して lint ツールを作成することは、最善の解決策ではない可能性があります。それは不可能かもしれません。代わりに単体テストのセットを作成してみませんか?

于 2013-06-25T17:21:16.310 に答える
1

質問の 2 番目の部分に答えるには:

これを実現するために、coffeescript でのコーディングは役立ちますか?

はいといいえ。あなたが与えた例は、セマンティクスに関連しています(最も厳格なモードのものと同様)。Coffeescript は構文を変更しますが、セマンティクスは同じままにします。

Coffeescript issue #1547では、coffeescriptサポートする構文チェックのいくつかの機能について説明しています。

さらに、CS が暗黙的に解決する、その問題で説明されていないいくつかのケースがあります。

  • 偶発的なグローバル変数:グローバル変数は、それらをアタッチすることによってのみ明示的に形成できますwindow
  • withブロック:そのようなブロックを形成する方法はありません。
  • 問題arguments スプラットで大幅に軽減されます

Coffeescript は少しは役に立ちますが、治療法ではありません。あなたはまだそれで自分の足を撃つことができますが、そうすることについてもう少し明確にすることを強制しようとします.

Coffeescript によって救われるもののほとんどは、JSHint と JSLint が解決しようとしている問題と同じであることを指摘しておく必要があります。別の言語に移動する代わりに、これらのいずれかを使用したい場合があります。

于 2013-06-30T23:51:33.723 に答える
-1

最善の策は、厳密モードのブラウザーでコードをテストすることだと思います。それが真の結果をもたらす唯一の方法です。

于 2013-06-28T23:56:02.447 に答える