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


7549

最近、CrockfordのJSLintを介してJavaScriptコードの一部を実行したところ、次のエラーが発生しました。

1行目の文字の問題1:「厳密な使用」ステートメントがありません。

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

それで"use strict";、何が何であり、それが何を意味し、それでもまだ関連性があるのでしょうか?

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


5
ここでの答えは古いですが、間違っています。ストリクトモードの主な理由は、プログラミングエラーを防止することではありませんでした。それは、静的に分析できるようにレキシカルにスコープを設定することでした:]
Benjamin

@BenjaminGruenbaum "use strict";単独で使用しても、JSのレキシカルスコープは設定されません。letおよびconstを使用して変数を宣言することも使用する必要があります。
Koorosh Pasokhi

ブロックスコープと字句スコープを混在させています。
Benjamin Gruenbaum

回答:


4938

Javascript Strict Modeに関するこの記事は興味深いかもしれません:John Resig-ECMAScript 5 Strict Mode、JSONなど

いくつかの興味深い部分を引用するには:

厳密モードはECMAScript 5の新機能で、プログラムまたは関数を「厳密な」操作コンテキストに配置できます。この厳密なコンテキストにより、特定のアクションが実行されなくなり、より多くの例外がスローされます。

そして:

厳格モードはいくつかの点で役立ちます。

  • 例外をスローして、いくつかの一般的なコーディングブループをキャッチします。
  • 比較的「安全でない」アクション(グローバルオブジェクトへのアクセス権の取得など)が行われた場合、エラーを防止またはスローします。
  • 混乱している、またはよく考えられていない機能を無効にします。

また、ファイル全体に「ストリクトモード」を適用できることにも注意してください...または、特定の機能にのみ使用できます(John Resigの記事からの引用)

// Non-strict code...

(function(){
  "use strict";

  // Define your library strictly...
})();

// Non-strict code... 

古いコードと新しいコードを混在させる必要がある場合に役立ちます;-)

ですから、"use strict"Perlで使用できるものと少し似ていると思います(そのため、名前は?)。破損につながる可能性のあるものをより多く検出することで、エラーを減らすのに役立ちます。

厳格モードは、すべての主要ブラウザでサポートされるようになりました

内部でネイティブのECMAScriptモジュール(とimportexport文)とES6クラス、strictモードは常に有効で、無効にすることはできません。


100
何年も経ってからデフォルトを変更しますか?それには遅すぎます。既存の多くのサイト/スクリプト/アプリケーションを壊してしまいます...将来のために、物事をより良くするのを助けることが唯一の可能なことです。
Pascal MARTIN

14
"use strict"Firefox 3.6、Safari 5、Chrome 7、Opera 10.6(すべてMac)で使用すると無効になる小さなコードスニペットを試しました。エラーはまったくないので、どのブラウザでもまだ「use strict」はサポートされていないと思います。IE9ではテストしませんでした;)
ハスキー

11
クイックアップデート:Firefox 4はストリクトモードを完全にサポートしており、私が知る限り、他のブラウザはサポートしていません。SafariとChromeは「部分的に」サポートされていますが、それが何を意味するのか本当にわかりません。
サーシャチェディゴフ2011

29
Chrome 11は、IE10がそうであるように、これらすべてのテストに合格するようですie.microsoft.com/testdrive/HTML5/TryStrict/Default.html#
gman

12
@Julius-これは、予約済みキーワードを使用して実装できなかった可能性があります。厳密なモードをトリガーしようとするコードは、古いブラウザーで機能しなくなるためです。「ランダムな」文字列リテラルを追加しても何も壊れません。
nnnnnn 2014年

1245

これはECMAScript 5の新機能です。JohnResigはそのすばらしい要約を書きまし

これは、JavaScriptファイルに(ファイルの上部または関数の内部に)配置した単なる文字列で、次のようになります。

"use strict";

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


328
速く失敗し、大声で失敗します。
Niels Bom

31
JavaScriptファイルをHTMLファイルにインラインで記述する場合は、新しいブロックをそれぞれで始めます<script>"use strict";。フラグは、それが含まれているブロックにのみ適用されます。
nobar 2013年

7
おかしい、これは文字列に単一引用符がなければならないという結果になりました。'use strict';代わりに書いてください
nilsi

1
次に、javascriptの巻き上げ概念はどうなりますか?
Sunil Sharma

1
@SunilSharma巻き上げようとしたが、変数が定義されていないため失敗した場合、現時点ではグローバルオブジェクトに追加されます。では"use strict";、代わりに失敗します。これは、それをグローバルオブジェクトに追加する場合、つまり次に関数を実行したときに機能しない可能性があることを意味します。つまり、最高のブロック(グローバル)にあるため、ブロックをリセットする別のことを行います。
wizzwizz4

646

このステートメント"use strict";は、JavaScriptの削減された安全な機能セットであるStrictモードを使用するようにブラウザーに指示します。

機能のリスト(非網羅)

  1. グローバル変数を許可しません。(var変数名の不足している宣言とタイプミスをキャッチします)

  2. サイレントで失敗した割り当ては、厳密モード(割り当てNaN = 5;)でエラーをスローします

  3. 削除できないプロパティを削除しようとすると、(delete Object.prototype)がスローされます

  4. オブジェクトリテラルのすべてのプロパティ名が一意である必要があります(var x = {x1: "1", x1: "2"}

  5. 関数パラメーター名は一意である必要があります(function sum (x, x) {...}

  6. 8進構文を禁止します(var x = 023;一部の開発者は、先行するゼロが数値を変更するために何もしないと誤って想定しています。)

  7. withキーワードを禁止します

  8. eval 厳密モードでは、新しい変数は導入されません

  9. プレーンネームの削除を禁止(delete x;

  10. 名前のバインドや割り当て、evalおよびarguments任意の形式の禁止

  11. 厳密モードでは、argumentsオブジェクトのプロパティに仮パラメータがエイリアスされません。(つまり、にバインドされてfunction sum (a,b) { return arguments[0] + b;}いるため、これは機能します。)arguments[0]a

  12. arguments.callee サポートされていません

[参照:厳格モードMozilla Developer Network ]


40
Nit:グローバル変数は許可されます。明示的でなければなりません(例:)window.foo = bar
gcampbell

1
オブジェクトリテラルのすべてのプロパティ名が一意である必要があります(var x = {x1: "1"、x1: "2"})これは有効です
Arun Killu

4
11の例には、aの変更がありません(それ以外の場合は意味がありません)。I. e。関数sum(a、b){a = 0; 引数を返す[0] + b; エイリアスが原因で、alert(sum(1、2))は、厳密モードでは3、厳密モードでは2を返します。
David Gausmann、2018年

413

人々がuse strictそれを使うことを心配しているなら、この記事をチェックする価値があるかもしれません:

ブラウザでのECMAScript 5 'Strict mode'のサポート。これは何を意味するのでしょうか?
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.
*/

116
同意しません。これはなぜそれが非常に役立つのかを示していると思います。本質的には、これは関数ではなく関数を返すことを意味しますwindow
Jamie Hutber '26 / 02/26

36
いつthisターゲットにできないウィンドウが欲しいwindowですか?
ジェイミーハットバー2013

14
それ自体を指します。thisグローバルウィンドウではなく、独自の機能に属しています
Jamie Hutber 2013

26
2番目のものthisは実際にありundefinedます。
Broxzier 2013

14
重要なのは、グローバルオブジェクトで暗黙的に間違った処理を行うのではなく、未定義のプロパティにアクセスするために、JSプログラムが失敗し始めることです。微妙なバグの追跡がはるかに簡単になります。
スティーブンチョン

208

注意が必要なのは、プログラマーにハードチャージするすべてのことです。"use strict"既存のコードに適用すると危険な場合があります。これは、コードを軽く叩いて「より良い」ものにすることができる、気分が良い、幸せそうなステッカーではありません。この"use strict"プラグマを使用すると、ブラウザーは、デフォルト/緩やかなJavaScriptが喜んで許可しているものの、厳密なJavaScriptを嫌う何かをしているという理由だけで、これまでスローされなかったランダムな場所で突然例外をスローします。あなたがコード内でめったに使用されていない呼び出しに隠された厳格違反があるかもしれません-それらが最終的に実行されたときにのみ例外をスローします-たとえば、あなたの支払い顧客が使用する本番環境で!

思い切って実行する場合は、"use strict"包括的なユニットテストと厳密に構成されたJSHintビルドタスクと共に適用することをお勧めします。厳格モードをオンにしました。または、ねえ、ここに別のオプションが"use strict"あります。レガシーコードに追加しないでください。正直なところ、その方法のほうがおそらく安全です。 絶対にないでください追加"use strict"のサードパーティのモジュールのように、あなたが所有していないか、維持する任意のモジュールに。

それは致命的な檻に入れられた動物"use strict"ですが、良いものになり得ますが、あなたはそれを正しく行わなければなりません。厳格にするのに最適な時期は、プロジェクトがグリーンフィールドであり、ゼロから始めるときです。JSHint/JSLintすべての警告とオプションをチームができる限り厳しく設定し、適切なビルド/テスト/アサートシステムを構築Grunt+Karma+Chaiして、すべての新しいモジュールをとしてマークし始めます"use strict"。多くの厄介なエラーと警告を解決する準備をしてください。JSHint/JSLint違反が発生した場合にビルドをFAILに構成して、全員が重要性を理解していることを確認してください。

私が採用し"use strict"たとき、私のプロジェクトはグリーンフィールドプロジェクトではありませんでした。その結果、"use strict"モジュールの半分がないので、IDEは赤いマークでいっぱいになり、JSHintはそれについて不平を言っています。これは、将来どのようなリファクタリングを行うべきかを思い出させてくれます。私の目標は、すべての不足している"use strict"発言のために赤点がないことですが、それは今から数年先です。


24
なぜこのスレッドの開発者は、「厳密な使用」については無頓着なのですか?それは、善のために、それ以外では機能するJavaScriptで例外をスローします!コーンフレークの砂糖のようにコードにそれを振りかけるだけですか?番号!悪い!"use strict"は慎重に使用する必要があります。できれば、すべての主要なブラウザーに対してユニットテストに合格し、すべてのコードパスを実行する単体テストを含む、ユーザーが制御するコードでのみ使用してください。あなたはテストを受けましたか?さて、あなたのために「厳格な使用」は問題ありません、あなた自身をノックアウトします。
DWoldrich、2014年

57
はい。明らかに「use strict」は、以前は壊れていなかったように見える一見有効なJavaScriptを壊す可能性があります。しかし、以前に壊れていないコードは、正しいコードであり、想定されていることを実行しているコードとは異なります。通常、宣言されていない変数を参照すると、タイプミスなどが通知されます。strictを使用すると、これらの種類のエラーを検出できます。できれば、製品コードを出荷する前に使用してください。
JosteinKjønigsen2015年

5
...または、コードの最後のパスの一部として「use strict」を適用し、明らかな問題をすべて修正し、肩をすくめて、「十分に良い」と言ってから、本番環境に取り出します:)
Wolfie Inu

13
個人的に、私は既存のコードを追加 "use strict";することはほとんどありません。そうは言っても、私が新しいコードを最初から作成するときは、ほとんど常にそれを使用します
Martin

3
ただし、すでにJSLintを使用している場合は、「use strict」を使用すると問題が発生する可能性のある場所のほとんどが修正されているはずです。
ジョナサンキャスト

179

を使用'use strict';しても、コードが突然改善されるわけではありません。

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

'use strict';

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

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

var a = 365;
var b = 030;

数値リテラルを揃えるという執念の中で、開発者は不注意にb8進リテラルで変数を初期化しました。非厳密モードは、これを24(base 10の)値を持つ数値リテラルとして解釈します。ただし、strictモードではエラーがスローされます。

ストリクトモードの専門分野の完全ではないリストについては、この回答を参照してください。


どこで使用すればよい'use strict';ですか?

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

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


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

  1. 'use strict';スクリプトの上にステートメントを挿入します。

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

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

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

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

    関数の字句スコープ内のすべてがdoSomething厳密モードで解釈されます。ここでは語彙スコープという言葉が重要です。たとえば、厳格なコードが厳格ではないライブラリの関数を呼び出す場合、コードのみが厳格モードで実行され、呼び出された関数は実行されません。詳細な説明については、この回答を参照してください。


ストリクトモードで禁止されていることは何ですか?

厳格モードで禁止されているいくつかのことを説明する素晴らしい記事を見つけました(これは排他的なリストではないことに注意してください):

範囲

これまで、JavaScriptは関数のスコープについて混乱してきました。静的スコープのように見える場合もありますが、一部の機能は動的スコープのように動作させます。これは混乱を招き、プログラムの読み取りと理解を困難にします。誤解はバグの原因になります。また、パフォーマンスの問題でもあります。静的スコープを使用すると、コンパイル時に変数バインディングを実行できますが、動的スコープの要件により、バインディングをランタイムに延期する必要があるため、パフォーマンスが大幅に低下します。

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

厳格なコードの利点の1つは、YUI Compressorなどのツールが 処理するときに、より優れた処理を実行できることです。

暗黙のグローバル変数

JavaScriptにはグローバル変数が含まれています。変数を明示的に宣言しない場合、グローバル変数が暗黙的に宣言されます。これにより、初心者は基本的な家事の一部を無視できるため、プログラミングが簡単になります。しかし、それは大規模なプログラムの管理をはるかに困難にし、信頼性を著しく低下させます。したがって、厳密モードでは、暗黙のグローバル変数は作成されなくなりました。すべての変数を明示的に宣言する必要があります。

グローバルリーク

this グローバルオブジェクトにバインドされる原因となる状況は多数あります。たとえばnew、コンストラクター関数を呼び出すときにプレフィックスを指定し忘れた場合、コンストラクターthisは予期せずグローバルオブジェクトにバインドされるため、新しいオブジェクトを初期化する代わりに、グローバル変数を静かに改ざんします。これらの状況では、ストリクトモードは代わりににバインドthisしますundefined。これにより、コンストラクターが代わりに例外をスローし、エラーをより早く検出できるようになります。

騒々しい失敗

JavaScriptには常に読み取り専用のプロパティがありましたが、ES5のObject.createProperty 関数がその機能を公開するまで自分で作成することはできませんでした。読み取り専用プロパティに値を割り当てようとすると、警告なしに失敗します。割り当てによってプロパティの値が変更されることはありませんが、プログラムはそのように処理されます。これは、プログラムが不整合な状態になる可能性がある完全性の危険です。厳密モードでは、読み取り専用プロパティを変更しようとすると、例外がスローされます。

オクタル

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

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

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

厳密モードでは、関数リテラルの重複キーは構文エラーを生成します。関数に同じ名前の2つのパラメーターを含めることはできません。関数は、パラメーターの1つと同じ名前の変数を持つことはできません。関数はdeleteそれ自身の変数を持つことはできません。delete設定不可能なプロパティへの試み は例外を投げるようになりました。プリミティブ値は暗黙的にラップされません。


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

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

implementsinterfaceletpackageprivateprotectedpublicstatic、およびyield


参考文献


2
とてもいい説明です。ただし、Angular jsなどの他のjavaスクリプトライブラリと組み合わせて「strict」モードを使用できるかどうか、疑問があります。
UVM 2016

3
@UVM:strict-modeディレクティブは字句スコープにのみ影響します。つまり、宣言されているファイル/関数のみです。'use strict'ディレクティブを持たない別のファイル/関数がある場合、厳密モードで実行されている関数から呼び出された場合でも、それらは非厳密モードで実行されます。説明については、こちらをご覧ください。
sampathsris 2016

これは完全に正しいわけではありません。'use strict'はコードの実行方法を変更します。
Cyber​​Ed 2016年

3
再確認すると、あなたは正しいです。例外を投げるだけだと思っていましたが、コードの動作方法は変更されませんでした(変更などthis)。今、私はあなたが他の関数を呼ぶことに言及しているのを見ます。
Cyber​​Ed 2016年

3
8進数が役立つ場合があります。そのためのC構文は恐ろしいですが、言語に新しい8進構文を追加して、先行ゼロ形式を非推奨にすることを望んでいました。もちろん、Javascriptが先行ゼロ形式をサポートしたのはばかげたことです。
スーパーキャット2017

138

私はすべての開発者に今から厳密モードを使い始めることを強くお勧めします。それをサポートする十分なブラウザがあり、ストリクトモードは、コードに含まれていることさえ知らなかったエラーから私たちを正当に救うのに役立ちます。

どうやら、初期段階では、これまでに発生したことのないエラーがあるでしょう。完全なメリットを得るには、すべてをキャッチしたことを確認するために、strictモードに切り替えた後に適切なテストを行う必要があります。間違いなくuse strict、コードを単に投入するだけでなく、エラーがないと想定しています。つまり、この信じられないほど有用な言語機能を使用してより良いコードを作成するときが来たということです。

例えば、

var person = {
    name : 'xyz',
    position : 'abc',
    fullname : function () {  "use strict"; return this.name; }
};

JSLintは、Douglas Crockfordによって作成されたデバッガーです。スクリプトに貼り付けるだけで、コード内の目立った問題やエラーをすばやくスキャンできます。


6
@JamieHutber:このリンクcaniuse.com/use-strict AND kangax.github.io/es5-compat-tableにアクセスしてください。それはすべてのブラウザに正確な考えを与えます。
2014年

95

他の答えを補完する、もう少し根拠のある答えを提供したいと思います。最も人気のある回答を編集したいと思っていましたが、失敗しました。私はできる限り包括的かつ完全なものにしようとしました。

詳細については、MDNのドキュメントを参照してください。

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

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

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

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

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

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

  • 厳密モードではTypeError、読み取り専用プロパティに割り当てたり、拡張不可能なオブジェクトに新しいプロパティを定義したりすると、が表示されます。(通常モードでは、どちらも単純にエラーメッセージなしで失敗します。)

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

4
「厳密モードでは、8進数リテラルは許可されません(これらは0x ...で始まるリテラルです)」8進数リテラルは先頭で始まり0ます。
Alex Gittemeier

83

私の2セント:

ストリクトモードの目標の1つは、問題のより迅速なデバッグを可能にすることです。これは、Webページのサイレントで奇妙な動作を引き起こす可能性がある特定の間違ったことが発生したときに例外をスローすることにより、開発者を支援します。を使用した瞬間use strictに、コードはエラーをスローします。これは、開発者が事前に修正するのに役立ちます。

使用後に学んだいくつかの重要なことuse strict

グローバル変数宣言を防止:

var tree1Data = { name: 'Banana Tree',age: 100,leafCount: 100000};

function Tree(typeOfTree) {
    var age;
    var leafCount;

    age = typeOfTree.age;
    leafCount = typeOfTree.leafCount;
    nameoftree = typeOfTree.name;
};

var tree1 = new Tree(tree1Data);
console.log(window);

現在、このコードはnameoftreeを使用してアクセスできるグローバルスコープで作成されますwindow.nameoftreeuse strictコードを実装するとエラーがスローされます。

キャッチされていないReferenceError:nameoftreeが定義されていません

Sample

withステートメントを排除:

withuglify-jsなどのツールを使用してステートメントを縮小することはできません。また、これらは非推奨になり、将来のJavaScriptバージョンから削除されます。

Sample

重複を防止:

プロパティが重複している場合、例外がスローされます

キャッチされていないSyntaxError:オブジェクトリテラルのデータプロパティの重複は、厳密モードでは許可されていません

"use strict";
var tree1Data = {
    name: 'Banana Tree',
    age: 100,
    leafCount: 100000,
    name:'Banana Tree'
};

他にもいくつかありますが、それについてもっと知識を深める必要があります。


ECMAScript 2015では、重複したプロパティ名が再び許可されます!MDNのドキュメントを参照してください。
philmcole

62

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

コマンドを囲む引用符は、コードが古いブラウザーでも機能することを確認します(厳密モードで構文エラーを生成するものは、通常、古いブラウザーで検出が困難な方法でスクリプトを誤動作させるだけです)。


12
次に、それは何をしますか?
アニッシュグプタ

7
...これは互換性を部分的に説明ますが、実際に何を行うかは説明ません。
コートシマ

58

を追加する"use strict";と、スクリプトが実行される前に次の場合にSyntaxErrorがスローされます。

  • 将来のECMAScriptバージョンの道を開く(予知するために新たに予約されたキーワードのいずれかを使用して、ECMAScriptの6): 、implementsinterfaceletpackageprivateprotectedpublicstaticおよびyield

  • ブロックでの関数の宣言

    if(a<b){ function f(){} }
  • 8進構文

    var n = 023;
  • this グローバルオブジェクトをポイントします。

     function f() {
          "use strict";
          this.a = 1;
     };
     f(); 
  • オブジェクトリテラルのプロパティ名に同じ名前を2回宣言しています

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

    ECMAScript 6ではこれは当てはまりません(バグ1041128)。

  • 同じ名前の関数を持つ2つの関数引数を宣言する

    f(a, b, b){}
  • 宣言されていない変数に値を設定する

    function f(x){
       "use strict";
       var a = 12;
       b = a + x*35; // error!
    }
    f();
  • delete変数名での使用delete myVariable;

  • evalまたはargumentsを変数または関数の引数名として使用する

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

出典:


ECMAScript 2015では、重複したプロパティ名が再び許可されます!MDNのドキュメントを参照してください。
philmcole

53

厳格モードでは、通常のJavaScriptセマンティクスにいくつかの変更が加えられます。

  • エラーをスローするように変更することにより、一部のJavaScriptサイレントエラーを排除します。

  • JavaScriptエンジンが最適化を実行するのを困難にする間違いを修正します。

  • ECMAScriptの将来のバージョンで定義される可能性があるいくつかの構文を禁止します。

詳細については、厳密モード -Javascriptをご覧ください


52

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

ルーラーを使用して行をまっすぐに行わないことを好む人は、通常、他の人にコードのデバッグを要求するページに行き着きます。

私を信じてください。オーバーヘッドは、不十分に設計されたコードと比較して無視できます。ここ数年、JavaScriptの上級開発者であるDoug Crockfordが非常に興味深い投稿をしています。個人的には、自分の良い習慣を忘れないように、いつも彼のサイトに戻りたいです。

最新のJavaScriptプラクティスは常に「厳密な使用」を呼び起こす必要があります。プラグマ。ECMAグループが「Strict」モードをオプションにした唯一の理由は、経験の浅いコーダーがJavaScriptにアクセスできるようにし、新しい安全なコーディング手法に適応する時間を与えるためです。


66
ストリクトモードがオプションである理由は、あなたが述べたこととは何の関係もありません。本当の理由は、適合しない可能性のある既存のコードを壊さないためです
Dexygen 2013年

17
確かに、経験の浅いプログラマーが「厳密な使用」を可能にする最初のプログラマーであるべきです。
Antti Haapala 2014

46

use strictこの時点からすべての機密性の高いJavaScriptファイルの最初に含めることは、より優れたJavaScriptプログラマーになるための小さな方法であり、ランダム変数がグローバルになり、物事が静かに変化するのを防ぎます。


42

w3schoolsからの引用

「厳密な使用」ディレクティブ

「use strict」ディレクティブはJavaScript 1.8.5(ECMAScriptバージョン5)で新しく追加されました。

これはステートメントではなく、リテラル式であり、以前のバージョンのJavaScriptでは無視されていました。

「厳密な使用」の目的は、コードを「厳密なモード」で実行する必要があることを示すことです。

ストリクトモードでは、たとえば、宣言されていない変数を使用することはできません。

なぜ厳密モードなのか?

厳格モードでは、「安全な」JavaScriptを簡単に記述できます。

厳密モードでは、以前に受け入れられていた「不正な構文」が実際のエラーに変わります。

たとえば、通常のJavaScriptでは、変数名を誤って入力すると、新しいグローバル変数が作成されます。厳密モードでは、これはエラーをスローし、誤ってグローバル変数を作成することを不可能にします。

通常のJavaScriptでは、開発者は書き込み不可能なプロパティに値を割り当てるエラーフィードバックを受け取りません。

厳密モードでは、書き込み不可能なプロパティ、getter-onlyプロパティ、存在しないプロパティ、存在しない変数、または存在しないオブジェクトへの割り当ては、エラーをスローします。

詳細については、http://www.w3schools.com/js/js_strict.aspを参照してください


37

"use strict"JavaScriptコードをstrictモードで実行できるようにします。つまり、基本的に、使用前にすべてを定義する必要があります。strictモードを使用する主な理由は、未定義のメソッドが誤ってグローバルに使用されるのを防ぐためです。

また、ストリクトモードでは、物事がより速く実行され、一部の警告またはサイレント警告は致命的なエラーをスローします。常に、より適切なコードを作成するために使用することをお勧めします。

"use strict"ECMA5で使用するには広く必要ですが、ECMA6ではデフォルトでJavaScriptの一部であるため、ES6を使用している場合は追加する必要はありません。

MDNの次のステートメントと例をご覧ください。

"use strict"ディレクティブ
"use strict"ディレクティブはJavaScript 1.8.5(ECMAScriptバージョン5)で新しく追加されました。これはステートメントではなく、リテラル式であり、以前のバージョンのJavaScriptでは無視されていました。「厳密な使用」の目的は、コードが「厳密なモード」で実行される必要があることを示すことです。ストリクトモードでは、たとえば、宣言されていない変数を使用することはできません。

「use strict」の使用例:
関数のStrictモード:同様に、関数のstrictモードを呼び出すには、正確なステートメント「use strict」を入力します。(または 'use strict';)他のステートメントの前の関数本体で。

1)関数の厳格モード

 function strict() {
     // Function-level strict mode syntax
     'use strict';
     function nested() { return 'And so am I!'; }
     return "Hi!  I'm a strict mode function!  " + nested();
 }
 function notStrict() { return "I'm not strict."; }

 console.log(strict(), notStrict());

2)スクリプト全体の厳格モード

'use strict';
var v = "Hi! I'm a strict mode script!";
console.log(v);

3)書き込み不可のグローバルへの割り当て

'use strict';

// Assignment to a non-writable global
var undefined = 5; // throws a TypeError
var Infinity = 5; // throws a TypeError

// Assignment to a non-writable property
var obj1 = {};
Object.defineProperty(obj1, 'x', { value: 42, writable: false });
obj1.x = 9; // throws a TypeError

// Assignment to a getter-only property
var obj2 = { get x() { return 17; } };
obj2.x = 5; // throws a TypeError

// Assignment to a new property on a non-extensible object.
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = 'ohai'; // throws a TypeError

MDNで詳細を読むことができます


31

ECMAScript委員会に参加していた一部の人々による良い話がありますJavaScriptへの変更、パート1:ECMAScript 5 "は、"use strict"スイッチの JavaScriptの実装者がすべてのWebサイトを突然壊すことなく、JavaScriptの多くの危険な機能をクリーンアップできるようになります。世界中。

もちろん、これらの機能の多くが(あった)ものであり、ECMAScript 5がそれらをどのように修正するかについても説明します。


27

比較する小さな例:

非厳格モード:

for (i of [1,2,3]) console.log(i)
    
// output:
// 1
// 2
// 3

厳格モード:

'use strict';
for (i of [1,2,3]) console.log(i)

// output:
// Uncaught ReferenceError: i is not defined

非厳格モード:

String.prototype.test = function () {
  console.log(typeof this === 'string');
};

'a'.test();

// output
// false

String.prototype.test = function () {
  'use strict';
  
  console.log(typeof this === 'string');
};

'a'.test();

// output
// true


2
上記のコードはi変数をグローバルスコープに追加することに注意してください(通常、これはベストプラクティスではなく、strictモードはそれを回避するのに役立ちます)。
マイケル

1
誰かが2番目の例を説明できますか?わかりません。this === 'a'両方の例ではいけませんか?
MaximeW

19

EcmaScript 5でuse strict導入され、それ以来維持されていることに注意してください。

ES6およびES7でストリクトモードをトリガーする条件は次のとおりです。

  • Use Strictディレクティブを含むディレクティブプロローグで始まる場合、グローバルコードはストリクトモードコードです(14.1.1を参照)。
  • モジュールコードは常に厳密なモードコードです。
  • すべての部品ClassDeclarationまたはClassExpressionは、 strictモードのコードです。
  • Evalコードは、Use Strictディレクティブを含むディレクティブプロローグで始まる場合、またはevalの呼び出しがストリクトモードコードに含まれる直接eval(12.3.4.1を参照)である場合、ストリクトモードコードです。
  • 関連するFunctionDeclaration、FunctionExpression、GeneratorDeclaration、GeneratorExpression、MethodDefinition、またはArrowFunctionが厳密モードコードに含まれている場合、または関数の[[ECMAScriptCode]]内部スロットの値を生成するコードがディレクティブプロローグで始まる場合、関数コードは厳密モードコードです。Use Strictディレクティブが含まれています。
  • 組み込みのFunctionおよびGeneratorコンストラクターに引数として提供される関数コードは、処理時に最後の引数がUse Strictディレクティブを含むディレクティブプロローグで始まるFunctionBodyである文字列である場合、厳密モードコードです。

14

開発者が使用する主な理由"use strict"は次のとおりです。

  1. グローバル変数の誤った宣言を防ぎます。を使用する"use strict()"var、使用前に変数が宣言されます。例えば:

    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. 注意:"use strict"ディレクティブは、スクリプトまたは関数の最初でのみ認識されます。
  3. 文字列"arguments"は変数として使用できません:

    "use strict";
    var arguments = 3.14;    // This will cause an error
  4. 変数としてのキーワードの使用を制限します。それらを使用しようとすると、エラーがスローされます。

つまり、エラーが発生しにくくなり、優れたコードを作成できるようになります。

詳細については、こちらを参照してください


12

「厳格に使用」; JavaScriptをもう少し堅牢にするECMAの取り組みです。それはJSにそれを少なくとも少し「厳格」にする試みをもたらします(他の言語は90年代から厳格なルールを実装しています)。実際には、JavaScript開発者に何らかのコーディングのベストプラクティスに従うよう「強制」します。それでも、JavaScriptは非常に壊れやすいものです。型付き変数、型付きメソッドなどはありません。JavaScript開発者には、JavaやActionScript3などのより堅牢な言語を学び、同じベストプラクティスをJavaScriptコードに実装することを強くお勧めします。デバッグ。


12

JavaScriptの「strict」モードはECMAScript 5で導入されました。

(function() {
  "use strict";
  your code...
})();

"use strict";JSファイルの最上部に書き込むと、厳密な構文チェックがオンになります。次のタスクを実行します。

  1. 宣言されていない変数に割り当てようとするとエラーが表示されます

  2. 主要なJSシステムライブラリの上書きを阻止

  3. 安全ではない、またはエラーが発生しやすい言語機能を禁止します

use strict個々の関数の内部でも機能します。use strictコードに含めることは常により良い方法です。

ブラウザの互換性の問題:「use」ディレクティブは、下位互換性を保つためのものです。それらをサポートしないブラウザは、それ以上参照されない文字列リテラルを見るだけです。ですから、彼らはそれを通り過ぎて先へ進みます。


12

use strict期待どおりに機能しない危険な機能を使用できないため、コードをより安全にする方法です。そして、以前に書かれたように、それはコードをより厳格にします。


11

Use Strictは、一般的なエラーと繰り返し発生するエラーを表示するために使用され、異なる方法で処理され、Javaスクリプトの実行方法を変更します。そのような変更は次のとおりです。

  • 偶発的なグローバルを防止

  • 重複なし

  • 排除する

  • この強制を排除する

  • より安全なeval()

  • 不変のエラー

詳細については、この記事を読むこともできます


11

通常、JavaScriptは厳密なルールに従っていないため、エラーの可能性が高くなります。を使用した後"use strict"、JavaScriptコードは、ターミネータの使用、初期化前の宣言など、他のプログラミング言語と同様の厳密なルールセットに従う必要があります。

"use strict"を使用する場合は、厳格な一連のルールに従ってコードを記述し、エラーや曖昧さの可能性を減らす必要があります。


7

「厳格に使用」; JavaScriptコードを「ストリクトモード」で実行する必要があることを定義します。

  • 「use strict」ディレクティブはECMAScriptバージョン5で新しく追加されました。
  • これはステートメントではなく、リテラル式であり、以前のバージョンのJavaScriptでは無視されていました。
  • 「厳密な使用」の目的は、コードを「厳密なモード」で実行する必要があることを示すことです。
  • ストリクトモードでは、たとえば、宣言されていない変数を使用することはできません。

Internet Explorer 9以下を除くすべての最新のブラウザーは「use strict」をサポートしています。

不利益

開発者がストリクトモードのライブラリを使用していて、通常モードでの作業に慣れている場合、期待どおりに機能しないいくつかのアクションをライブラリで呼び出す可能性があります。

さらに悪いことに、開発者は通常モードであるため、余分なエラーがスローされるという利点がないため、エラーがサイレントに失敗する可能性があります。

また、上記のように、strictモードでは特定の操作を実行できなくなります。

人々は一般的にそもそもそれらのものを使用すべきではないと考えていますが、一部の開発者は制約を嫌い、言語のすべての機能を使用したいと考えています。


4

厳格モードは、メモリリークを防ぐことができます。

非厳密モードで記述された以下の関数を確認してください:

function getname(){
    name = "Stack Overflow"; // Not using var keyword
    return name;
}
getname();
console.log(name); // Stack Overflow

この関数では、次の変数を使用しています name、関数内で。内部的には、コンパイラーは最初に、その特定の関数スコープで特定の名前で宣言された変数があるかどうかをチェックします。コンパイラーはそのような変数がないことを理解したので、外側のスコープをチェックインします。私たちの場合、それはグローバルスコープです。この場合も、コンパイラはその名前のグローバルスペースで宣言された変数がないことを理解しているため、グローバルスペースでこのような変数を作成します。概念的には、この変数はグローバルスコープで作成され、アプリケーション全体で使用できます。

別のシナリオは、たとえば、変数が子関数で宣言されていることです。その場合、コンパイラーは外部スコープ、つまり親関数でその変数の有効性をチェックします。それからはじめて、それはグローバル空間をチェックインし、そこで私たちのために変数を作成します。つまり、追加のチェックを行う必要があります。これは、アプリケーションのパフォーマンスに影響します。


次に、同じ関数をストリクトモードで記述します。

"use strict"
function getname(){
    name = "Stack Overflow"; // Not using var keyword
    return name;
}
getname();
console.log(name); 

次のエラーが発生します。

Uncaught ReferenceError: name is not defined
at getname (<anonymous>:3:15)
at <anonymous>:6:5

ここで、コンパイラは参照エラーをスローします。厳密モードでは、コンパイラーは変数を宣言せずに使用することを許可しません。したがって、メモリリークを防ぐことができます。さらに、より最適化されたコードを記述できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.