web-dev-qa-db-ja.com

「厳格モード」とは何ですか?

私はMozilla Developer NetworkでJavaScriptリファレンスを探していましたが、"strict mode"と呼ばれるものに出会いました。私はそれを読んで、それが何をするのか理解するのに苦労しています。誰かがその目的が何であり、どのように役立つかを一般的に簡単に説明できますか?

130
nkcmr

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

コードの先頭にある"use strict";を他の何かの前に追加するだけです。

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

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

ほとんどの場合、任意のスコープの真ん中にグローバル変数を作成するつもりはないため、ほとんどの場合、blah = 33エラーであり、プログラマーは実際にそれをグローバル変数にしたくなかったので、彼らはvar blah = 33を書くつもりでした。

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

ストリクトモードのMDNページで詳細を読む

147
Simon Sarris

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

こんなこと

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

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

privateMethodプロパティが無駄にグローバルオブジェクトに追加されるのではなく、undefinedが呼び出されたときに(bにプロパティを追加できないため)エラーが発生します。

33
Adam Rackis

厳密なモードが追加されたため、EcmaScriptの簡単に静的に分析可能なサブセットが存在し、将来のバージョンの言語の良いターゲットになります。ストリクトモードは、ストリクトモードに制限する開発者がミスを少なくし、バグが明らかになることを期待して設計されました。

ハーモニー 、これはEcmaScriptの次のメジャーバージョンになることを期待し、ES5 strictの上に構築されます。

HarmonyはES5の厳格なモードに基づいて構築され、モードが多すぎることを回避します。

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

SES(Secure ECMAScript)設計実験

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

SESからES5/Strictへの直接的な翻訳が必要です。

Annex C 規格では、厳格モードと通常モードの違いが説明されています。

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

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

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サイレントエラーを排除します。

インスタンスの場合:厳密モードを使用したコード

enter image description here

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

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

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

// Will not throw an error

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

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

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

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

  • 厳格モードは、JavaScriptエンジンが最適化を実行するのを困難にする間違いを修正します。

  • strictモードは、ECMAScriptの将来のバージョンで定義される可能性のある一部の構文を禁止します。

5
Renganathan M G

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

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


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

1
Tilak Maddy

ECMAScript5は、いくつかの新しいオブジェクトとプロパティを導入し、いわゆる"strict mode"も導入します。

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

"use strict";
1
Vahid Hallaji

質問:
次は私が遭遇した問題です。チュートリアルに従っていましたが、次の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...

解決策:
したがって、gulp-sassモジュール内にあるindex.jsファイルが表示されます(基本的にロックされているため、編集しないでください)。しかし、強制的に"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.js gulpモジュールファイルに対して行った変更を元に戻しました。そして今、それはスムーズに実行されます。

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

0
Randika Vishman