strictモードでは、町に来ている

2010年12月14日14:12で、ダグラス·クロックフォードから|で開発 | 20コメント

これは、世界中の人々は、ECMAScriptプログラミング言語標準、第5版のECMA総会の承認の一周年を記念して、その違いを忘れ、平和と交わりを一緒に来る時間や季節である。 ES5の中で最も重要な機能は、新しい厳格なモードです。 strictモードでは、OPT-モードでの言語のほとんどの問題は機能の一部を修理または削除することです。

Strictモードを指定する

strictモードを要求するには、2つの方法があります。 最初にこのプラグマを挿入することである

  "厳格な使用"; 

ファイルまたはコンパイル単位の先頭に表示されます。 これは、任意の他のステートメントの前に現れなければなりませんが、それは空白やコメントを付けることができます。 それは役に立たない文字列リテラル文の形式を持っているので、ES3システムによって無視されます。 これはまた古いブラウザ上で実行できるプログラムをES5/strict書くことが可能であることを意味します。 厳格なコードは、非厳密な(あるいはずさんな )コードと対話することができますので、厳格な機能がずさんな関数を呼び出すことができますし、ずさんな機能は、厳密な関数を呼び出すことができます。 この互換性の高いレベルは、strictモードでの採用が容易になります。

を持つファイルまたはコンパイル·ユニット内のコードのすべて"use strict";プリアンブルは、厳密なコードとして処理されます。 問題がある、しかし。 パフォーマンスの考慮事項は、現在私たちが累積HTTPの遅延を避けるために、一緒に多くのJavaScriptファイルを連結するために強いる。 を持つファイルの場合"use strict";プリアンブルはそれに追加ずさんなコードを持って、ずさんなコードが厳しいとして処理され、おそらく失敗します。 簡単なルールがあります:同一ファイル内で厳格かつずさんな混在させることはできませんが、我々はすでにいくつかの有名なWebサイトがこの間違ったを取得してきました。

二番目の方法は、プラグマは、関数の最初の文のようになります。挿入することです。 これは、関数全体が内にネストされたすべての機能を含む、厳格になることを宣言しています。 厳密性を尊重関数スコープなので、厳密なコードとずさんなコードが同じファイルに混在させることができます。 この二番目の形式は非常にうまく機能モジュールのパターンとその多くのバリエーション。 それは連結の危険を回避するため二番目の形式は好ましい。

  (関数(){
    "厳格な使用";
    / /この関数は厳密である...
 }());

 (関数(){
    / /しかし、この関数はずさんである...
 }()); 

範囲

歴史的には、JavaScriptは関数のスコープです。方法について混乱されています。 時には彼らは静的スコープと思われるが、一部の機能は、動的スコープであるようにそれらを動作させる。 これは読んで理解するのが難しいプログラムを作り、混乱しています。 誤解は、バグを引き起こします。 また、パフォーマンスの問題です。 静的スコープは、コンパイル時に発生するバインディング変数を許可しますが、動的スコープのための要件は、バインディングが大幅なパフォーマンスのペナルティが付属してランタイムに延期される必要があることを意味します。

厳密モードでは、すべての変数バインディングは静的に行われている必要があります。 それは以前に動的バインディングを必要とする機能を排除または変更する必要があることを意味します。 具体的には、 withステートメントが除去され、 eval呼び出し元の環境を改ざんするための機能の能力が厳しく制限されています。

厳格なコードの利点の一つは、のようなツールということであるYUI Compressorは、それを処理するときに良い仕事を行うことができます。

暗黙のグローバル変数

JavaScriptはグローバル変数を暗黙的にしています。 明示的に変数を宣言しない場合、グローバル変数は、暗黙的にあなたのために宣言されています。 彼らは基本的な家事の雑用の一部を無視することができるので、これは初心者のためのプログラミングが容易になります。 しかし、それは大規模なプログラムの管理がはるかに困難になり、それが信頼性が大幅に低下します。 したがって、strictモードでは、暗黙のグローバル変数は、もはや作成されません。 あなたが明示的にすべての変数を宣言する必要があります。

グローバルリーク

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

騒々しい失敗

JavaScriptは常に読み取り専用プロパティを持っていましたが、ES5年代までは、それらを自分で作成できませんでしたObject.createProperty関数は、その能力を露呈した。 読み取り専用プロパティに値を代入しようとすると、それは静かに失敗しました。 代入は、プロパティの値を変更しないだろうが、それが持っていたかのようにプログラムが進みました。 これは、プログラムが不整合な状態になることがあります整合性の危険性があります。 strictモードでは、読み取り専用のプロパティを変更しようとすると、例外がスローされます。

8進数の

ワードサイズが3の倍数であったマシン上のマシンレベルのプログラミングを行うときに数字の8進数(または基数8)の表現は非常に有用であった。 60ビットのワードサイズを持っていたCDC 6600メインフレームで作業するときは、8進数を必要としていました。 あなたは8進数を読み取ることができれば、あなたは20桁、単語を見て可能性があります。 2桁はopコードを表し、1桁の8個のレジスタのいずれかを同定した。 マシンコードから高レベルの言語にゆっくりと移行中に、それはプログラミング言語で8進形式を提供するために有用であると考えられていた。

Cでは、octalnessの非常に不幸な表現が選ばれました:リーディングゼロ。 したがって、C言語で、0100は64ではなく、100を意味し、08はエラーではなく、8です。 さらに残念なことに、この時代錯誤は、それがエラーのみを作成するために使用されるJavaScriptなど、ほぼすべての近代的な言語にコピーされています。 それは他の目的を持っていません。 したがって、strictモードでは、8進形式は、もはや許されません。

エトセトラ

arguments疑似配列は、ES5でもう少しのような配列になります。 strictモードでは、その失ったcalleecallerプロパティを示しています。 これにより、あなたの合格することができるarguments秘密のコンテキストの多くを与えることなく、信頼できないコードに。 また、 argumentsの関数のプロパティが除去されます。

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

あなたのプログラムに合格した場合JSLint 、それはおそらく、strictモードで動作します。

それはまだ不完全な世界です

strictモードでは対応していないことがJavaScriptでの問題が残っています。 たとえば、セミコロンの挿入は、まだ危険です、0.1 + 0.2は依然として0.3と等しくありません。 これらの問題の修正は、将来の版を待つ必要があります。

なぜ厳格なモード事項

プログラムの信頼性と読みやすさに明らかな利点に加えて、strictモードでは、マッシュアップの問題を解決するために役立っています。 我々は、コード、ブラウザを引き継ぐために、ユーザーまたは当社のサーバーに自分自身を詐称するライセンスを与えることなく、我々と我々のユーザーのために有用な事をする私たちのページにサードパーティのコードを招待できるようにしたい。 我々は、サードパーティのコードを制約する必要があります。 のようなシステムGoogleのカハは 、パフォーマンスと不便で、大幅なコストで、これを行います。 私自身のADsafeのシステムは、これを行いますが、排除の費用でthis[]の採用が困難になる可能性が言語から添字。 strictモードでは、私たちはADsafeとカハの表現力の利便性とパフォーマンスをサードパーティのコードを行うことができます。 私たちのサイトがより複雑になり、より多くの接続されて、これは非常に重要になります。

厳密モードでは、XSSの問題を解決していません。 その問題を解決するには、依存するいくつかの肯定的な行動を取るW3C

ES5/strictは、プレビューになりました、すぐにどこでもすべての規格に準拠したブラウザで標準装備となります。

共有および拡張: del.icio.usでブックマーク | Diggそれ! | reddit!

20コメント

  1. いつも素晴らしい記事として! ES5は、将来の... Object.create()、Object.defineProperty()、Object.isExtensible()、Array.isArray()は、JSONのネイティブサポートが大きな特徴である.. ADsafeをチェックアウトし、有望に見える

    によるコメントセバスArmeli - 2010年12月14日

  2. arguments.calleeのが出ている場合は、その本体からラムダを参照する別の方法は何ですか?

    によるコメントArieh - 2010年12月15日

  3. 完全にstrictモードに準拠しているすべてのブラウザ(ベータ版かどうか)はありますか?

    ネイトによるコメント- 2010年12月15日

  4. @ Arieh、うん -

    var carl = function bob(a) {
    if (!a) { bob(1); } // reference scoped to inside this function
    alert(carl === bob); // gotcha - true in all browsers but false in ie...
    };

    コメントby クリス - 2010年12月15日

  5. Arieh:あなたは、関数式に名前を付け、その名前によってそれらを参照することができます。 例えば、 var x = function lookMaNoYCombinator(a, b) { if (a === 0) return a + b; else return lookMaNoYCombinator(a - 1, b) }

    によるコメントサミSamhuri - 2010年12月15日

  6. @ Arieh:あなたが再帰的にしたい場合は、名前付きラムダを使用する必要があります。 例えば、。 (関数f(){F()})。 これ|これは、引数に反対していないバインディングの利点があります|

    コメントby オリバー - 2010年12月15日

  7. @ネイト:WebKitとFirefoxのナイトリービルドは、両方のstrictモードに準拠しなければならない、我々はすべてを見つけた場合はバグが提出されている感謝し、任意の(AT http://bugs.webkit.orghttp://bugs.mozilla.org)

    コメントby オリバー - 2010年12月15日

  8. さまざまなブラウザでES5の互換性を示す優れたチャートはここで見つけることができます: http://kangax.github.com/es5-compat-table/

    コメントby ジミー - 2010年12月15日

  9. とeval注入'と' 本当に動的バインディングを実装していませんでした さらにフルES3は、すべてのケースでレキシカル束縛を(静的バインディングとは限らないが)を使用します。 これらの機能は確かにかかわらず、混乱した。

    デイビッド·サラホップウッドによるコメント- 2010年12月16日

  10. ダグラスこんにちは、

    良い概要、ありがとうございました。 さらに、私はあなたの読者が詳細なstrictモードの説明に興味があると確信して: http://dmitrysoshnikov.com/ecmascript/es5-chapter-2-strict-mode/

    PS:追加/修正のペア:

    関数は、パラメータの1つとして同じ名前を持つ変数を持つことはできません。

    これは、引数の1つとして同じ名前の変数宣言を持ってもOKです。 それが既に引数の結合を介して宣言されているので技術的に、宣言は、単にスキップされます。

    この関数は、独自の変数を削除することはできません。

    それは常にそうであった-変数(使用して作成したものを除いてevalコンテキスト)を常に持っている{} DontDelete ES3 /で[構成] = falseをES5で。 すなわち、それにかかわらず、strictモードを変数を削除することはできません。

    ドミトリー。

    によるコメントドミトリーA. Soshnikov - 2010年12月17日

  11. YUI3は、そのモジュールに "厳格な使用"を追加しますか?

    デイヴィッドによるコメント- 2010年12月17日

  12. こんにちはダグラス、

    私はあなたのポストからの文の下に混乱しています。

    "Strictモードでは、すべての変数バインディングは静的に行われている必要があります。 "以前に動的バインディングを必要とする機能を排除または変更する必要がありますことを意味

    キーワード "これは" - それは、動的バインディングまたはレキシカル(静的な)結合を持っていますか?

    それは動的バインディングを持っている場合は、私たちは、strictモードでは、 'this'の使用を停止すべきと言って意味ですか?

    私は本当に混乱しています。 私はあなたのビデオプレゼンテーションから最後の一ヶ月からJavaScriptを学び始めた。 彼らは非常に非常に便利です。 これは私の最初のプログラミング言語です。 私の疑問はここで非常に奇妙であるかもしれません。

    しかし、単に 'this'の疑いであなたから聞きたい。

    感謝

    によるコメントekanna - 2010年12月28日

  13. strictモードでは、メソッドの形式は以前と同じようにオブジェクトにこれをバインドします。 関数形は未定義ではなく、グローバルオブジェクトにこれをバインドします。

    によるコメントダグラスクロックフォード - 2010年12月29日

  14. ドミトリー、あなただけのあなたがして削除することができる変数を作ることができるケースを説明した! delete演算子の構文はそのような場合のために正確に変数を可能にします。 しかし、それ以上。

    とデビッド·サラ、あなたが分割している毛は非常に短いです。

    によるコメントダグラスクロックフォード - 2010年12月29日

  15. ダグラスは感謝しています。

    によるコメントekanna - 2011年1月7日

  16. "ノイズ障害"の誤字を修正することができセクション "createProperty"は "defineProperty"である必要があります。

    トラヴィスによるコメント- 2011年1月11日

  17. "厳密に素晴らしい"

    フランツenzenhoferによるコメント- 2011年1月13日

  18. クロックフォードrockz!

    マルクドラコによるコメント- 2011年1月20日

  19. だから、ときにYUI Compressorは、 "厳格な使用"をドロップし停止します。minifaction中のコードからプラグマ? :)

    によるコメントmarcoos - 2011年2月3日

  20. S / minifaction /縮小/

    によるコメントmarcoos - 2011年2月3日

申し訳ありませんが、コメントフォームは、この時点でクローズされます。

ヤフーが主催する

著作権©2006-2012ヤフー株式会社すべての権利を保有。 プライバシーポリシー - サービス利用規約

を搭載ワードプレスヤフー ウェブホスティング