「ストリクトモード」とは何ですか、またどのように使用されますか?


134

Mozilla Developer NetworkでJavaScriptリファレンスを調べてきたところ、と呼ばれるものに出会いました"strict mode"。それを読み直しましたが、それが何をするのか理解できません。誰かが(一般的に)その目的が何であるか、そしてそれがどのように役立つかを簡単に説明できますか?


回答:


149

その主な目的は、より多くのチェックを行うことです。

"use strict";他の何よりも前に、コードの先頭に追加するだけです。

たとえば、blah = 33;は有効なJavaScriptです。つまり、完全にグローバルな変数を作成しますblah

しかし、厳密モードでは、変数の宣言にキーワード「var」を使用しなかったため、エラーになります。

ほとんどの場合、任意のスコープの途中でグローバル変数を作成するつもりはありません。そのため、blah = 33書き込まれるほとんどの時間はエラーであり、プログラマーは実際にはそれをグローバル変数にしたくありませんでした。書きvar blah = 33ます。

同様に、技術的に有効な多くのことを禁止します。NaN = "lol"エラーは発生しません。また、NaNの値は変更されません。厳密なthis(および同様の奇妙なステートメント)を使用すると、エラーが発生します。これまでに書く理由がないので、ほとんどの人はこれを高く評価しますNaN = "lol"ます。

厳密モードのMDNページで詳細を読む


4
これはMDNでのドキュメントの完全な複製です
nkcmr '28

23
その効用についてあなたは何を理解していませんか?これは、有効である可能性が最も高いエラーであるものをキャッチすることにより、開発を支援することを目的としています。
Simon Sarris、2011

34

Simonの回答でまだ言及されていない厳密モードの1つの側面は、関数呼び出しによって呼び出された関数で厳密モードが設定thisundefinedれることです。

このようなもの

function Obj() {
   this.a = 12;
   this.b = "a";
   this.privilegedMethod = function () {
      this.a++;
      privateMethod();
   };

   function privateMethod() {
     this.b = "foo";
   }
}

privateMethod呼び出すとエラーが発生します(プロパティをに追加できないためundefinedb。プロパティをグローバルオブジェクトに無用に追加するのではありません。


4
ええ、追加privateMethod.bind(this)();して呼び出す必要がありますnew jsbin.com
hlcs '15年


21

厳密なモードが追加されたので、EcmaScriptの静的に分析可能なサブセットが容易になり、将来のバージョンの言語のターゲットとして適しています。また、厳密モードは、厳密モードに制限する開発者がミスを減らし、バグがより明確に現れることを期待して設計されました。

EcmaScriptの次のメジャーバージョンになると期待されるHarmonyは、ES5 strictの上に構築される予定です。

HarmonyはES5の厳密なモードに基づいて構築されているため、モードが多すぎないようになっています。

他のいくつかの言語実験もstrictモードに依存しています。 SESはES5 strictモードの分析可能性に依存しています。

SES(Secure ECMAScript)設計実験

ES5 / Strictの機能を削除または修復して、オブジェクト機能プログラミング言語を設計します。

SESからES5 / Strictへの直接的な変換があるはずです。

付録C標準のは、厳密モードと通常モードの違いを説明しています。

厳格なモードの制限と例外

  • 識別子「implements」、「interface」、「let」、「package」、「private」、「protected」、「public」、「static」、および「yield」は、strictモードコード内のFutureReservedWordトークンとして分類されます。(7.6.12 [?])。
  • 準拠モードの実装では、ストリクトモードコードを処理するときに、B.1.1で説明されているように、NumericLiteral(7.8.3)の構文を拡張してOctalIntegerLiteralを含めることはできません。
  • 厳密なモードコード(10.1.1を参照)を処理する場合、準拠する実装は、B.1.2で説明されているように、EscapeSequenceの構文を拡張してOctalEscapeSequenceを含めることはできません。
  • 宣言されていない識別子または解決できない参照への割り当ては、グローバルオブジェクトにプロパティを作成しません。strictモードのコード内で単純な割り当てが発生した場合、そのLeftHandSideは解決できない参照に評価されてはなりません。それを行うと、ReferenceError例外がスローされます(8.7.2)。また、LeftHandSideは、属性値{[[Writable]]:false}のデータプロパティ、属性値{[[Set]]:undefined}のアクセサープロパティ、または存在しないものへの参照ではない場合があります。 [[Extensible]]内部プロパティの値がfalseであるオブジェクトのプロパティ。これらの場合、TypeError例外がスローされます(11.13.1)。
  • 識別子evalまたは引数は、代入演算子(11.13)またはPostfixExpression(11.3)のLeftHandSideExpressionとして、または接頭辞インクリメント(11.4.4)または接頭辞デクリメント(11.4.5)演算子によって操作されるUnaryExpressionとして表示されない場合があります。 。ストリクトモード関数のArgumentsオブジェクトは、アクセス時にTypeError例外をスローする「caller」および「callee」という名前の設定不可能なアクセサプロパティを定義します(10.6)。
  • ストリクトモード関数のArgumentsオブジェクトは、配列のインデックス付きプロパティ値を、関数の対応する仮パラメーターバインディングと動的に共有しません。(10.6)。ストリクトモード関数の場合、引数オブジェクトが作成されると、ローカル識別子引数の引数オブ​​ジェクトへのバインディングは不変であり、割り当て式のターゲットにならない場合があります。(10.5)。
  • ストリクトモードコードに、データプロパティの定義が複数あるObjectLiteral(11.1.5)が含まれている場合は、SyntaxErrorです。Identifier "eval"またはIdentifier "arguments"が、strictコードに含まれるPropertyAssignmentのPropertySetParameterListのIdentifierとして発生する場合、またはそのFunctionBodyがstrictコード(11.1.5)の場合は、SyntaxErrorです。
  • 厳密モードのevalコードは、evalを呼び出す呼び出し元の変数環境で変数または関数をインスタンス化できません。代わりに、新しい変数環境が作成され、その環境は評価コード(10.4.2)の宣言バインディングのインスタンス化に使用されます。
  • これがストリクトモードコード内で評価される場合、this値はオブジェクトに強制変換されません。this値がnullまたは未定義の場合、グローバルオブジェクトに変換されず、プリミティブ値はラッパーオブジェクトに変換されません。関数呼び出し(Function.prototype.applyおよびFunction.prototype.callを使用して行われた呼び出しを含む)を介して渡されたthis値は、渡されたthis値をオブジェクト(10.4.3、11.1.1、15.3.4.3、15.3。 4.4)。
  • ストリクトモードコード内で削除演算子が発生すると、そのUnaryExpressionが変数、関数引数、または関数名への直接参照である場合、SyntaxErrorがスローされます(11.4.1)。
  • ストリクトモードコード内で削除演算子が発生すると、削除するプロパティの属性が{[[Configurable]]:false}(11.4.1)の場合、TypeErrorがスローされます。厳密なコード内でVariableDeclarationまたはVariableDeclarationNoInが発生し、そのIDがevalまたは引数(12.2.1)の場合は、SyntaxErrorです。
  • 厳格モードのコードにWithStatementを含めることはできません。このようなコンテキストでのWithStatementの発生は、SyntaxError(12.10)です。
  • Catchを含むTryStatementが厳密なコード内で発生し、Catchプロダクションの識別子がev​​alまたは引数である場合は、SyntaxErrorです(12.14.1)。
  • 識別子evalまたは引数が、strictモードのFunctionDeclarationまたはFunctionExpression(13.1)のFormalParameterList内にある場合は、SyntaxErrorです。
  • ストリクトモード関数は、同じ名前を持つ2つ以上の仮パラメーターを持つことはできません。FunctionDeclaration、FunctionExpression、またはFunctionコンストラクターを使用してこのような関数を作成しようとすると、SyntaxError(13.1、15.3.2)になります。
  • 実装は、この仕様で定義されているものを超えて拡張することはできません。つまり、呼び出し元という名前のプロパティのストリクトモード関数内、または関数インスタンスの引数です。ECMAScriptコードは、strictモードの関数(10.6、13.2、15.3.4.5.3)に対応する関数オブジェクトのこれらの名前を持つプロパティを作成または変更しない場合があります。
  • strictモードコード内で識別子evalまたは引数をFunctionDeclarationまたはFunctionExpressionの識別子として、または仮パラメーター名(13.1)として使用するのはSyntaxErrorです。Functionコンストラクター(15.3.2)を使用して、このようなストリクトモード関数を動的に定義しようとすると、SyntaxError例外がスローされます。

6

ECMAScript 5は、strictモードの概念を導入しました。

コードで厳格モードを呼び出す

厳格モードは、スクリプト全体または個々の関数に適用されます。{}括弧で囲まれたブロックステートメントには適用されません。そのようなコンテキストに適用しようとしても何も起こりません。

スクリプト全体:

app.jsを作成しているため、最初のステートメント使用スクリプトを追加すると、コード全体にストリクトモードが適用されます。

// app.js whole script in strict mode syntax
use strict”;
// Now you can start writing your code 

関数の厳密モード:

関数に対してストリクトモードを呼び出すには、「use strict」という正確なステートメントを入力します。関数本体の先頭の他のステートメントの前。

function yourFunc(){
 "use strict";

 // Your function code logic
}

厳格モードでは、通常のJavascriptセマンティクスにいくつかの変更が組み込まれています。最初のストリクトモードは、JavaScriptサイレントエラーを変更してエラーをスローすることにより、JavaScriptサイレントエラーを排除します。

インスタンスの場合:厳格モードを使用するコード

ここに画像の説明を入力してください

上記のコード例では、コードでストリクトモードを使用していません。エラーはスローされません。x宣言せずに変数にアクセスしているので。そのため、厳密モードで宣言されていない変数にアクセスすると、エラーがスローされます。

では、厳密モードなしで宣言せずに変数xにアクセスしてみましょう。

(function(){
    x = 3;
})();

// Will not throw an error

ストリクトモードを使用する利点:

  • エラーをスローすることにより、JavaScriptサイレントエラーを排除します。
  • JavaScriptエンジンが最適化を実行するのを困難にする間違いを修正します。
  • 厳密モードではない同一のコードよりもコードを高速に実行できるようにする
  • ECMAScriptの将来のバージョンで定義される可能性があるいくつかの構文を禁止します。

5

Strictモードは、通常のJavaScriptセマンティクスにいくつかの変更を加えます。

  • strictモードは、エラーをスローするように変更することで、JavaScriptのサイレントエラーを排除します。

  • strictモードは、JavaScriptエンジンが最適化を実行するのを困難にする誤りを修正します。

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


1

ECMAScript5 いくつかの新しいオブジェクトとプロパティを紹介し、いわゆる "strict mode"

厳格モードは、非推奨の機能を除外する言語のサブセットです。ストリクトモードはオプトインで必須ではありません。つまり、コードをストリクトモードで実行する場合は、次の文字列を使用して(関数ごとに1回、またはプログラム全体に対して1回)意図を宣言します。

"use strict";

1

2017と私は最終的にドキュメントを見つけました:https :
//developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

厳格モードは、JavaScriptの制限付きバリアントをオプトインする方法です。Strictモードは単なるサブセットではありません。意図的に通常のコードとは異なるセマンティクスを持っています。厳密モードをサポートしないブラウザーは、厳密モードコードを実行しますが、ブラウザーとは異なる動作をするため、厳密モードの関連する側面のサポートを機能テストすることなく、厳密モードに依存しないでください。ストリクトモードコードと非ストリクトモードコードは共存できるため、スクリプトはストリクトモードを段階的に選択できます。


Strictモードは、通常のJavaScriptセマンティクスにいくつかの変更を加えます。まず、ストリクトモードは、エラーをスローするように変更することにより、JavaScriptサイレントエラーをいくつか排除します。第2に、ストリクトモードは、JavaScriptエンジンが最適化を実行するのを困難にするミスを修正します。ストリクトモードコードは、ストリクトモードではない同一のコードよりも高速に実行できる場合があります。3番目に、strictモードでは、ECMAScriptの将来のバージョンで定義される可能性のある一部の構文が禁止されています。


0

質問:
私が遭遇した問題は次のとおりです。私はチュートリアルに従っていましたが、次のscssファイルをコンパイルしてCSSコードを生成しようとしましたが、

.fatty{
  width: percentage(6/7);
}

次のgulpfile.jsタスクを使用:

var gulp = require('gulp');
var sass = require('gulp-sass');

gulp.task('sass', function () {
    return gulp.src('app/scss/styles.scss')
        .pipe(sass())
        .pipe(gulp.dest('app/css'))
});

だから私が得ているエラーは次のとおりです:

~/htdocs/Learning/gulp1/node_modules/gulp-sass/index.js:66
    let sassMap;
    ^^^

SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode
    at exports.runInThisContext (vm.js:53:16)
    at Module._compile (module.js:373:25)
// stacktrace here...

解決策:
それでindex.js、私のgulp-sassモジュール内にあるファイルが表示されます(これは基本的にロックされており、編集すべきではありません)。しかし、私が強制的に行っ"use_strict"てそのindex.jsファイルの先頭にを追加すると、タスクがスムーズに実行されます。

私は無力だったので、これを解決策として使い続けています!しかし、他のいくつかのSO Q&Aを行った後、私は次のような答えを見つけました

sudo npm install -g n
sudo n stable

そしてすぐにNodeJを(Version10.xに)更新し、ターミナルからの指示に従って次のコマンドを実行してGulpを再構築しました。

npm rebuild node-sass --force

そして、それはすべて大丈夫です。それが解決された方法です。index.jsgulpモジュールファイルに対して行った変更を元に戻しました。そして今、それはスムーズに実行されます。

この答えが誰かに役立つことを願っています!

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