9

JavaScript で次の関数を定義しています。

function _snr(id) {
    "use strict";
    this.e = "something";
}

JSLint を使用してコードを実行したところ、関数に「use strict」を追加するよう提案されました。

私がe今行うと、未定義のエラーがスローされます。thisいくつかの初期調査から、以前参照していた_snrものはもはや定義されていないように見えます。

「use strict」について読み、安全でない慣行を防ぐために使用されていることを発見しました。これについて何が危険だったのか、誰か説明できますか? 「厳密な使用」が実際に行っていることと、コードを修正するにはどうすればよいですか?

4

1 に答える 1

11

を設定せずに関数が呼び出された場合、thisnon-strict モードでthisはグローバル (ブラウザのウィンドウ) オブジェクトを参照するように設定されます。厳密モードでは、未定義のままになります。

関数が呼び出された_snr(...)場合、その関数はthis設定されていないため、非厳密モードthisではグローバル オブジェクトに設定され、グローバルプロパティthis.e = ...が参照 (または代入によって作成) されます。e

ただし、厳密モードthisでは未定義になり、未定義のプロパティにアクセスしようとするとエラーがスローされます。

ECMA-262 §10.4.3 Entering Function Codeで説明されています。

編集

厳密モードと非厳密モードの両方と一致する方法で関数内からグローバル オブジェクトにアクセスする場合は、次のようなものを使用できます。

var _snr = (function(global) {
    return function (id) {
        global.e = "something";
    };
}(this));

非厳密モードでは、次のことができます。

function _snr(id) {
    var global = (function(){return this;}());
    global.e = "something";
}

関数内でグローバルオブジェクトを参照するためglobal、関数がどのように呼び出されるかについて心配する必要はありません。しかし、2 番目の例は厳密モードでは機能しません。

その他の回答:

「use strict」について読み、安全でない慣行を防ぐために使用されていることを発見しました。これについて何が危険だったのか、誰か説明できますか?

この特定のケースでは絶対に何もありません。

ただし、より一般的なケースでは、グローバル オブジェクトへの直接アクセスを停止するコンテキスト内でコードを実行できるようにすることをお勧めします。上記の 2 番目の例は、厳密でないコードでそれを行う方法 (つまり、関数コンテキスト内からグローバル オブジェクトに直接アクセスする方法) を示しています。

「use strict」が実際に行っていること

呼び出しでまたはthisに設定すると、グローバル オブジェクトへの設定が停止します。その結果については、上記を参照してください。undefinednull

どうすればコードを修正できますか?

上記を参照。

ああ、最後に、ECMA-262 Annex C The Strict Mode of ECMAScriptに厳密モードの有益な要約があります。

于 2012-11-07T06:23:59.447 に答える