4

私はJavaScriptプログラミングスタイルについて考えていましたが、暗黙のグローバルを使用するという簡単に犯される間違いを防ぐために、構文糖衣構文を少し追加するのが理にかなっているのではないかと考えていました。

var OuterFunction = function() { // closure container
    var renamedCounter = 0; // someone renamed counter,
    this.resetCounter = function () {
        counter = 0; // ... but forgot to check the inner functions as well.
        return this;
    };
    return this;
}

この例では、counterは突然グローバル変数になり、のインスタンスにローカルスコープされる変数になりますOuterFunction

クロージャでキャプチャされた変数を「宣言」することで、割り当てvoidに使用する他のコードと同様に、自由なアサーションを取得できます。 counter

this.resetCounter = function () {
    void counter; // this will throw an Error if counter is not in scope.
    counter = 0;
    return this;
};

編集jleedevが指摘したように、変数名自体を使用するだけで、変数名が存在するかどうかをテストするようです。

this.resetCounter = function () {
    counter;
    counter = 0;
    return this;
};

同様に機能します。

私が見る利点は次のとおりです。

  • 書くのは短いです。
  • ある程度、変数宣言のように見えます。
  • 追加のために編集:一貫して行われると、構文チェッカー(肉またはプログラム)がこの種のエラーを見つけるのが非常に簡単になります。

一方で:

  • ややこしい。コードは実際には何もしませ
  • 将来の通訳者は、それを無意味で副作用のないコードとして見つけ、最適化する可能性があります。

私が見落としている側面はありますか?これはばかげた考えですか、それとも少なくともある程度防御可能ですか?

質問者の編集:これはコミュニティWikiの質問である必要がありますが、それに変更するためのチェックボックスが表示されません。ぼんやりと覚えています。

壮大な愚かさのために編集:もちろん、+=インクリメントする前に式の値を取得しようとします。そのため、少し意味があるように、例の名前をresetCounterではなくに変更しました。incrementCounter

4

2 に答える 2

3

ECMASCript 言語仕様によると:

11.4.2voidオペレーター

プロダクション UnaryExpression : void UnaryExpression は次のように評価されます。

  1. UnaryExpression を評価した結果を expr とします。
  2. GetValue(expr) を呼び出します。
  3. 未定義を返します。

注 GetValue は、目に見える副作用がある可能性があるため、その値が使用されていなくても呼び出す必要があります。

したがって、最適化して取り除くべきではありません。

ただし、私見では、変数を「宣言」するようにリモートで見えるわけではなく、確かに変数のように動作しないため、避ける必要があります。

編集:実際には、変数が実際に「ゲッター」を持つプロパティである場合など、GetValue 呼び出しに副作用がある可能性があるため、正確には使用しないでください。

于 2011-03-12T18:41:46.950 に答える
1

これがあなたの質問に対する答えかどうかはわかりませんが、ECMAScript 5では、暗黙的なグローバル宣言を防ぐstrict モードが導入されています。

宣言されていない識別子または解決できない参照への代入は、グローバル オブジェクトにプロパティを作成しません。厳格モードのコード内で単純な代入が発生した場合、そのLeftHandSideが解決できない Reference に評価されてはなりません。その場合、ReferenceError例外がスローされます ( 8.7.2 )。LeftHandSide は、属性値 {[[Writable]]: false }を持つデータ プロパティへの参照、属性値 {[[Set]]: undefined }を持つアクセサ プロパティへの参照、または存在しないプロパティへの参照であってはなりません。 [[Extensible]] 内部プロパティの値がfalseであるオブジェクトのプロパティ。これらの場合、TypeError例外がスローされます ( 11.13.1)。

それをサポートするブラウザー (現時点では Firefox 4 のみのようです) では、strict モードを有効にすることができます。

"use strict";

開発中は、JSLintを使用してファイルにエラーや問題のあるコードがないかチェックします。暗黙のグローバルについて通知します。

于 2011-03-12T19:16:17.040 に答える