JavaScriptで「厳密に使用する」とは何ですか?その背後にある理由は何ですか?



12 Answers

これは、ECMAScript 5の新機能です。John Resig氏は、 その素晴らしい要約を書いています。

これは、あなたのJavaScriptファイル(ファイルの先頭または関数の中のいずれか)に次のように記述した文字列です。

"use strict";

これをあなたのコードに入れてみると、現在のブラウザでは文字列のように問題はありません。 あなたのコードがプラグマに違反すると、将来あなたのコードに問題が生じる可能性があります。 たとえば、 foo = "bar"を最初に定義していなければ、コードは失敗し始めます。これは私の意見では良いことです。

Question

最近、私はJavaScriptコードの一部をCrockfordのJSLintで実行しましたが、次のエラーが発生しました:

1行目の問題文字1: "厳格な"文がありません。

いくつかの検索をして、私はいくつかの人々が"use strict";追加することを認識した"use strict"; JavaScriptコードに変換します。 ステートメントを追加すると、エラーが表示されなくなりました。 残念ながら、Googleはこの文字列の背景に歴史の多くを明らかにしていませんでした。 確かに、JavaScriptがブラウザによってどのように解釈されるかとは何かが関係しているはずですが、私はその効果がどうなるか分かりません。

だから、 "use strict";とは何ですか? すべてについて、それは何を意味し、それはまだ関連していますか?

現在のブラウザーのどれかが"use strict";対応していますか? 文字列か、それとも将来の使用のためですか?




昨年リリースされたブラウザを使用している場合、JavaScript Strictモードをサポートしている可能性が最も高いです。 ECMAScript 5が現在の標準になる前の古いブラウザだけが、それをサポートしていません。

コマンドの引用符は、厳密なモードで構文エラーを生成するものは一般的に、古いブラウザーでは検出が困難な一部のスクリプトが誤動作するだけで、古いブラウザーでもコードが引き続き機能することを確認します。




When adding "use strict"; , the following cases will throw a SyntaxError before the script is executing:

  • Paving the way for future ECMAScript versions , using one of the newly reserved keywords (in prevision for ECMAScript 6 ): implements , interface , let , package , private , protected , public , static , and yield .

  • Declaring function in blocks

    if(a<b){ function f(){} }
    
  • Octal syntax

    var n = 023;
    
  • this point to the global object.

     function f() {
          "use strict";
          this.a = 1;
     };
     f(); 
    
  • Declaring twice the same name for a property name in an object literal

     {a: 1, b: 3, a: 7} 
    

    This is no longer the case in ECMAScript 6 ( bug 1041128 ).

  • Declaring two function arguments with the same name function

    f(a, b, b){}
    
  • Setting a value to an undeclared variable

    function f(x){
       "use strict";
       var a = 12;
       b = a + x*35; // error!
    }
    f();
    
  • Using delete on a variable name delete myVariable;

  • Using eval or arguments as variable or function argument name

    "use strict";
    arguments++;
    var obj = { set p(arguments) { } };
    try { } catch (arguments) { }
    function arguments() { } 
    

ソース:




"厳密な使用"; プログラマがJavaScriptのゆるいプロパティや悪いプロパティを使用しないという保険です。 それは、あなたが直線を作るのを手助けするようなガイドです。 「Strictを使用する」は、「ストレートコーディング」を行うのに役立ちます。

ルーラーを使用して直線を直線的に使用したくない人は、通常、他の人がコードをデバッグするよう求めているページで終わります。

私を信じてください。 オーバーヘッドは、設計が不適切なコードと比較して無視できる程度です。 数年前からシニアJavaScript開発者として活躍していたDoug Crockford氏は、ここでは非常に興味深い投稿をしています 。 個人的には、自分のサイトにいつも戻って、自分の良い習慣を忘れないようにしたい。

現代のJavaScriptの習慣は、常に「厳密な使用」を呼び起こすべきです。 プラグマ。 ECMA Groupが「厳格」モードをオプションにした唯一の理由は、 経験の少ないコーダーにJavaScriptへのアクセスを許可し、新しい安全なコーディング手法に適応する時間を与えることです。




"use strict"; is the ECMA effort to make JavaScript a little bit more robust. It brings in JS an attempt to make it at least a little "strict" (other languages implement strict rules since the 90s). It actually "forces" JavaScript developers to follow some sort of coding best practices. Still, JavaScript is very fragile. There is no such thing as typed variables, typed methods, etc. I strongly recommend JavaScript developers to learn a more robust language such as Java or ActionScript3, and implement the same best practices in your JavaScript code, it will work better and be easier to debug.




Normally java script does not follow strict rules hence increasing chances of errors. After using "use strict" , the java script code should follow strict set of rules as like in other programming languages such as use of terminators, declaration before initialization etc.

If "use strict" is used then the code should be written by following a strict set of rules hence decreasing the chances of errors and ambiguities.




Just wanted to add some more points.

The Reason to Use Strict Mode--->

  • Strict mode makes it easier to write "secure" JavaScript.

  • Strict mode changes previously accepted "bad syntax" into real
    errors.

  • As an example, in normal JavaScript, mistyping a variable name
    creates a new global variable.

  • In strict mode, this will throw an error, making it impossible to accidentally create a global variable.

  • In strict mode, any assignment to a non-writable property, a
    getter-only property, a non-existing property, a non-existing
    variable, or a non-existing object, will throw an error.

The things that will throw errors in Strict Mode Using a variable, without declaring it, is not allowed:

"use strict";
 x = 3.14;                // This will cause an error

Objects are variables too.

Using an object, without declaring it, is not allowed:

  "use strict";
  x = {p1:10, p2:20};      // This will cause an error

Deleting a variable (or object) is not allowed.

  "use strict";
   var x = 3.14;
   delete x;                // This will cause an error

For security reasons, eval() is not allowed to create variables in the scope from which it was called:

"use strict";
 eval ("var x = 2");
 alert (x);               // This will cause an error

f()のような関数呼び出しでは、この値はグローバルオブジェクトでした。strictモードでは、未定義です。

"use strict"は、スクリプトの先頭でのみ認識されます。




他の答えを補完するために、もう少し基礎的な答えを提供したいと思います。 私は最も一般的な答えを編集することを望んでいたが、失敗した。 私はできる限り包括的かつ完全なものにしようとしました。

詳細については、 MDNのマニュアルを参照してください。

ECMAScript 5で導入された"use strict"ディレクティブ。

ディレクティブはステートメントと似ていますが、まだ異なります。

  • use strictはキーワードを含んでいません:このディレクティブは、特別な文字列リテラル(一重引用符または二重引用符で囲まれた)からなる単純な式文です。 ECMAScript 5を実装していないJavaScriptエンジンは、単に副作用のない式文を参照するだけです。 ECMAScript標準の将来のバージョンでは、実際のキーワードとしてのuse導入される予定です。 引用符は廃止される。
  • use strictは、スクリプトや関数の先頭でのみ使用できます。つまり、他のすべての(実際の)文に先行する必要があります。 関数のスクリプトの最初の命令である必要はありません。文字列リテラルで構成された他のステートメント式の前に置くことができます(JavaScriptの実装では、実装固有の指令として扱うことができます)。 最初の実際のステートメント(スクリプトまたは関数内)に続く文字列リテラルステートメントは、単純な式ステートメントです。 通訳者は、それらを指示として解釈してはならず、効果がありません。

use strictディレクティブは、次のコード(スクリプトまたは関数内)が厳密なコードであることを示します。 スクリプトの最高レベルのコード(関数内にないコード)は、スクリプトにuse strictディレクティブが含まれている場合、厳密なコードとみなされます。 関数自体が厳密なコードで定義されている場合、または関数にuse strictディレクティブが含まれている場合、関数の内容は厳密なコードとみなされます。 eval()メソッドに渡されるコードは、厳密なコードからeval()が呼び出されたとき、またはuse strictディレクティブを含んでいるときは厳密なコードとみなされます。

ECMAScript 5の厳密なモードは、JavaScript言語の限定されたサブセットであり、言語の適切な欠点を排除し、より厳しいエラーチェックとより高いセキュリティを備えています。 strictモードとnormalモードの違いを以下に示します(そのうちの最初の3つが特に重要です)。

  • with -statementはstrictモードwithは使用できません。
  • strictモードでは、すべての変数を宣言する必要があります。グローバルObject変数、関数、関数パラメータ、catch節パラメータ、またはプロパティとして宣言されていない識別子に値を代入すると、 ReferenceError返されます。 通常モードでは、識別子はグローバル変数(グローバルObjectプロパティとして)として暗黙的に宣言され、
  • strictモードでは、 thisキーワードは、関数として呼び出された関数では値がundefinedです(メソッドではありません)。 (通常モードでは、 this常にグローバルObject指します)。 この違いは、実装がstrictモードをサポートしているかどうかをテストするために使用できます。
var hasStrictMode = (function() { "use strict"; return this===undefined }());
  • また、関数がcall()またはstrictモードでapplythiscall()またはapply()呼び出しの最初の引数の値とまったく同じです。 (ノーマルモードでは、 nullundefinedはグローバルObject置き換えられ、 Objectではない値はオブジェクトにキャストされます)。

  • 厳密モードでは、読み取り専用のプロパティに割り当てるか、拡張不可能なオブジェクトの新しいプロパティを定義しようとすると、 TypeErrorます。 (通常モードでは両方ともエラーメッセージなしで失敗します)

  • strictモードでは、 eval()コードを渡すときに、呼び出し元のスコープ内で変数や関数を宣言または定義することはできません(通常モードで行うことができます)。 代わりに、 eval()新しいスコープが作成され、変数と関数はそのスコープ内にあります。 eval()実行が終了すると、そのスコープは破棄されます。
  • strictモードでは、関数のarguments-objectには、その関数に渡される値の静的コピーが含まれます。 通常のモードでは、arguments-objectはやや魔法のような振る舞いをします。配列の要素と名前付き関数のパラメータは、同じ値を参照します。
  • strictモードでは、 delete演算子の後に非修飾識別子(変数、関数、または関数パラメータ)が続くと、 SyntaxErrorが返されます。 通常モードでは、 delete式は何もせず、 false評価されfalse
  • strictモードでは、構成できないプロパティーを削除しようとするとTypeErrorします。 (通常モードでは、試行は単に失敗し、 delete式はfalse評価されfalse )。
  • strictモードでは、オブジェクトリテラルと同じ名前の複数のプロパティを定義しようとすると、構文エラーとみなされます。 (通常モードではエラーは発生しません)。
  • strictモードでは、関数宣言に同じ名前の複数のパラメータがある場合、構文エラーとみなされます。 (通常モードではエラーは発生しません)。
  • strictモードでは、8進リテラルは許されません(これらはリテラルで、 0xで始まります)。(通常のモードでは、8進リテラルを使用できる実装もあります)
  • strictモードでは、識別子evalargumentsはキーワードのように扱われます。 値を変更することはできず、値を割り当てることもできず、変数、関数、関数パラメーター、またはcatchブロックの識別子の名前として使用することはできません。
  • 厳密なモードでは、呼び出しスタックを調べる可能性についてより多くの制限があります。 arguments.callerarguments.calleeは、strictモードの関数でTypeErrorさせます。 さらに、厳密なモードでの関数の呼び出し側および引き数のプロパティによっては、それらを読み込もうとするとTypeErrorします。



'use strict'; 突然コードを良くすることはありません。

JavaScript strictモードは、 ECMAScript 5の機能です。 strictモードを有効にするには、スクリプト/関数の先頭にこれを宣言します。

'use strict';

JavaScriptエンジンがこのディレクティブを見ると、特別なモードでコードの解釈が始まります。 このモードでは、潜在的なバグである可能性のある特定のコーディング手法が検出されたときにエラーがスローされます(厳密モードの背後にある理由です)。

この例を考えてみましょう。

var a = 365;
var b = 030;

彼らは、数値リテラルを整理するために、変数bを8進リテラルで不注意に初期化しています。 厳密でないモードでは、数値24 (10進数)の数値リテラルとして解釈されます。 ただし、strictモードではエラーが発生します。

厳密なモードでの専門の非網羅的なリストについては、 この回答を参照してください。

どこで'use strict';使用'use strict';べきですか? ?

  • 私の新しい JavaScriptアプリケーションでは: 絶対に! Strictモードは、コードで何か愚かなことをしているときに、内部通報者として使用することができます。

  • 私の既存の JavaScriptコード: 恐らくそうではありません! 既存のJavaScriptコードにstrictモードで禁止されているステートメントが含まれている場合、アプリケーションは単純に機能しなくなります。 strictモードが必要な場合は、既存のコードをデバッグして修正する準備が必要です。 これは'use strict';理由'use strict'; 突然コードを良くすることはありません

厳格なモードを使用するにはどうすればよいですか?

  1. 'use strict';挿入し'use strict'; あなたのスクリプトの上の文:

    // File: myscript.js
    
    'use strict';
    var a = 2;
    ....
    

    myscript.jsファイル内のすべてがstrictモードで解釈されることに注意してください。

  2. または、 'use strict';挿入し'use strict'; 関数本体の上にあるステートメント:

    function doSomething() {
        'use strict';
        ...
    }
    

    関数のレキシカルスコープ内のすべてのものは、厳密なモードで解釈されます。 単語の語彙範囲はここで重要です。 より良い説明については、 この回答を参照してください。

厳格なモードで禁止されているものは何ですか?

私は厳密なモードで禁止されているいくつかのことを記述した素敵な記事を見つけました(これは排他的なリストではありません)。

範囲

歴史的に、JavaScriptは関数のスコープの仕方について混乱していました。 場合によっては静的スコープに見える場合もありますが、動的スコープのように動作する機能もあります。 これは混乱し、プログラムの読み込みや理解が難しくなります。 誤解はバグを引き起こす。 また、パフォーマンス上の問題です。 静的スコープを使用すると、コンパイル時に変数バインディングが発生する可能性がありますが、動的スコープの要件は、実行時にバインドを延期しなければならないことを意味します。

厳密モードでは、すべての変数バインディングが静的に実行される必要があります。 つまり、以前は動的バインディングが必要だった機能を排除または変更する必要があります。 具体的には、with文が削除され、eval関数の呼び出し元の環境を改ざんする機能が厳しく制限されています。

厳密なコードのメリットの1つは、 YUI Compressorのようなツールは、処理するときにより良い仕事をすることができるということです。

暗黙のグローバル変数

JavaScriptにはグローバル変数が含まれています。 変数を明示的に宣言しないと、グローバル変数が暗黙的に宣言されます。 これは、基本的なハウスキーピング作業の一部を怠る可能性があるため、初心者にとってプログラミングを容易にします。 しかし、それは大規模なプログラムの管理をはるかに困難にし、信頼性を大幅に低下させます。 厳密なモードでは、暗黙のグローバル変数はもはや作成されません。 すべての変数を明示的に宣言する必要があります。

グローバルリーク

thisをグローバルオブジェクトにバインドさせる可能性のある状況はいくつかあります。 たとえば、コンストラクタ関数を呼び出すときにnew接頭辞を指定するのを忘れた場合、コンストラクタはグローバルオブジェクトに予期せずバインドされるため、新しいオブジェクトを初期化する代わりに、静かにグローバル変数を改ざんします。 このような状況では、strictモードではthisundefinedにバインドします。 thisによりコンストラクタは例外をスローし、エラーを早期に検出できます。

騒々しい失敗

JavaScriptには常に読み取り専用のプロパティがありますが、ES5のObject.createProperty関数がその機能を公開するまで、JavaScriptを独自に作成することはできませんでした。 読み取り専用プロパティーに値を代入しようとすると、暗黙的に失敗します。 この割り当てはプロパティの値を変更することはありませんが、あなたのプログラムはそれが持っていたかのように進んでいきます。 これは、プログラムが矛盾した状態になる可能性のある完全性の危険です。 strictモードでは、読み取り専用プロパティを変更しようとすると例外がスローされます。

オクタル

ワード数が3の倍数であるマシンでマシンレベルのプログラミングを行う場合、数値の8進数(またはベース8)の表現は非常に役に立ちました。ワードサイズが60ビットのCDC 6600メインフレームで作業する場合、8進数が必要でした。 8進数を読むことができれば、単語を20桁で見ることができます。 2桁は演算コードを表し、1桁は8個のレジスタのうちの1つを識別した。 マシンコードから高水準言語への移行が遅い間に、プログラミング言語で8進形式を提供することは有用であると考えられていました。

Cでは、非常に不幸な8進表現が選択されました。先行ゼロ。 したがって、Cでは0100は100ではなく64を意味し、 08はエラーではなく8である。さらに残念なことに、この時代錯誤は、JavaScriptを含むほぼすべての現代の言語にコピーされており、エラーを作成するためにのみ使用されます。 他の目的はありません。 厳密なモードでは、8進形式はもはや許されません。

その他

引数の擬似配列は、ES5では配列のようになります。 strictモードでは、 calleecallerプロパティが失われます。 これにより、多くの機密コンテキストを諦めることなく、信頼できないコードにargumentsを渡すことが可能になります。 また、関数のargumentsプロパティも削除されています。

strictモードでは、関数リテラルのキーが重複すると構文エラーが発生します。 関数は、同じ名前の2つのパラメータを持つことはできません。 関数は、そのパラメータの1つと同じ名前の変数を持つことはできません。 関数はそれ自身の変数をdeleteことはできません。 構成できないプロパティーをdeleteしようとdelete 、例外がスローされるようになりました。 プリミティブ値は暗黙的にラップされません。

将来のJavaScriptバージョン用の予約語

ECMAScript 5は予約語のリストを追加します。 それらを変数または引数として使用すると、strictモードでエラーが発生します。 予約語は次のとおりです。

implementsinterfaceletpackageprivateprotectedpublicstaticyield

参考文献




The main reasons why developers should use "use strict" are:

  1. Prevents accidental declaration of global variables.Using "use strict()" will make sure that variables are declared with var before use. 例えば:

    function useStrictDemo(){
     'use strict';
     //works fine
     var a = 'No Problem';
    
     //does not work fine and throws error
     k = "problem"
    
     //even this will throw error
     someObject = {'problem': 'lot of problem'};
    }
    
  2. NB: The "use strict" directive is only recognized at the beginning of a script or a function.
  3. The string "arguments" cannot be used as a variable:

    "use strict";
    var arguments = 3.14;    // This will cause an error
    
  4. Will restrict uses of keywords as variables. Trying to use them will throw errors.

In short will make your code less error prone and in turn will make you write good code.

To read more about it you can refer http://www.w3schools.com/js/js_strict.asp .




There's a good talk by some people who were on the ECMAScript committee: Changes to JavaScript, Part 1: ECMAScript 5" about how incremental use of the "use strict" switch allows JavaScript implementers to clean up a lot of the dangerous features of JavaScript without suddenly breaking every website in the world.

Of course it also talks about just what a lot of those misfeatures are (were) and how ECMAScript 5 fixes them.




use strict心配している人は、この記事をチェックする価値があります。

ECMAScript 5ブラウザでの '厳密モード'のサポート。 これは何を意味するのでしょうか?
NovoGeek.com - クリシュナのウェブログ

それはブラウザのサポートについて語っていますが、もっと重要なのはそれを安全に処理する方法です:

function isStrictMode(){
    return !this;
} 
/*
   returns false, since 'this' refers to global object and 
   '!this' becomes false
*/

function isStrictMode(){   
    "use strict";
    return !this;
} 
/* 
   returns true, since in strict mode the keyword 'this'
   does not refer to global object, unlike traditional JS. 
   So here, 'this' is 'undefined' and '!this' becomes true.
*/



Note that use strict was introduced in EcmaScript 5 and was kept since then.

Below are the conditions to trigger strict mode in ES6 and ES7 :

  • Global code is strict mode code if it begins with a Directive Prologue that contains a Use Strict Directive (see 14.1.1).
  • Module code is always strict mode code.
  • All parts of a ClassDeclaration or a ClassExpression are strict mode code.
  • Eval code is strict mode code if it begins with a Directive Prologue that contains a Use Strict Directive or if the call to eval is a direct eval (see 12.3.4.1) that is contained in strict mode code.
  • Function code is strict mode code if the associated FunctionDeclaration, FunctionExpression, GeneratorDeclaration, GeneratorExpression, MethodDefinition, or ArrowFunction is contained in strict mode code or if the code that produces the value of the function's [[ECMAScriptCode]] internal slot begins with a Directive Prologue that contains a Use Strict Directive.
  • Function code that is supplied as the arguments to the built-in Function and Generator constructors is strict mode code if the last argument is a String that when processed is a FunctionBody that begins with a Directive Prologue that contains a Use Strict Directive.



Related