2012-04-07 3 views
4

グローバルスコープを '汚染する'ため、名前空間を使用すべきではないと言われました。私は何が選択肢だろうか?JavaScriptで名前空間が悪いと思われるのはなぜですか?

ユーティリティ関数や定数を定義したいとします。ウェブサイトの場合、簡単な方法は名前空間でそれらを定義することです。グローバルスコープへのダメージはオブジェクト1つに限定されます。

名前空間は悪い習慣であれば、質問のカップルが頭に浮かぶ:

  1. なぜこの悪い習慣はありますか?
  2. この宣言の対象は何ですか(ウェブアプリケーション/動的ウェブサイト/静的ウェブサイトなど)ですか?
  3. 代替手段はありますか?

この質問はa post on the benefits of using extend.jsに開始議論の結果です。

+6

そして、私はいつもネームスペースはグローバルスコープを汚染していないと思っていました。(彼らは**良い**です)。 –

+1

ええ、誰かがこれを後方に持っています。 –

+3

@FelixKling名前空間は、依然としてグローバルスコープを汚染します。 JavaScriptではグローバルトークンは必要ありません。それらを使用する人は誰でもそれを間違ってやっています。 – Raynos

答えて

8

この悪い習慣はなぜですか?

名前空間自体は不要なコンセプトなので悪いです。

プロパティとメソッドを持つオブジェクトを持つことは許容されます。また、 "名前空間"に似た "モジュール"トークンを持つこともできますが、その意味は、すべてのプロパティとメソッドを含むファイルごとに1つの "モジュール"トークンがあることです。これは "名前空間"とは異なります。なぜなら、単一のファイルで作成/変更されただけであり、グローバルトークンとして公開されていないからです。

この宣言(ウェブアプリケーション/ダイナミックウェブサイト/静的ウェブサイトなど)の有効範囲は何ですか?

すべてのECMAScript、新しいグローバルトークンを作成することはありません

選択肢は何ですか?

名前空間を持つ代わりに、複数の "ファイルローカル"トークンを優先する必要があります。つまり、各ファイル/モジュールをクロージャーでラップする必要があり、このクロージャー内の複数のローカル変数にアクセスする必要があります。

グローバル変数は、まったく必要ないので、悪いこともあります。グローバルを避ける方法は、すべてを閉じて、外部のjavascriptファイルをロードする方法をインテリジェントにすることです。ゼログローバルモジュールローダの

さらにリーディング:

+0

AMDの 'define'と' require'関数は2つのグローバルのみが必要です。 ;) – Lucero

+1

ゼログローバルが必要です。トークン 'define'と' require'を他のグローバルトークンでモジュールに注入することができます – Raynos

+0

申し訳ありませんが、ここで私を失ってしまいました。私がAMD準拠のローダーを使用していて、モジュールを定義したいのであれば、私は 'define(...)'を行います - 'define'がそこに存在しなければグローバルではありませんか? (当然私の定義ではなく、AMDローダーによって定義されています。)また、実際にモジュールを使用するコードをロードして実行する場合も同じですが、そこには 'require'が必要です。 – Lucero

2

は個人的に私はあなたが決してはグローバルスコープを汚染しなければならないと言う人が適切に「汚染」を定義することができないと思います。例えば、ネイティブのMathオブジェクトでこれをある程度見ることができます。私が知っている他のすべてのプログラミング言語は、すべての数学関数を単純な関数として持っていますが、JSはそうではありません。しかし、これを極限に抑えるならば、単純な警告ボックスは例えばcore.dialog.alertとなります。

変数をきれいに保つために、すべてのコードをクロージャーで囲むのが好きです。しかし、私のメインのJSスクリプトファイルは、カスタムAlert()、またはAJAX()などの汎用スコープのユーティリティ機能を多数定義しています。私は頻繁にそれらを使用するつもりなら、私は名前空間呼び出しでファイルを膨らませる必要はありません。そして、私はすべての変数をクロージャーで定義するので、関数を誤って上書きする危険はありません(私はクロージャ自体でそうするかもしれませんが、グローバルスコープには影響しません)。

全体として、名前空間は過大評価されています。すでにコードを書いておき、すべての単一のwindowプロパティで泣かないでください。

+3

グローバル変数を使用することをお勧めする人は、これは悪い習慣です。 – Raynos

+1

名前空間やその他の手法は、競合する可能性のあるライブラリを階層化した環境ではるかに役立ちます。たとえば、JIRAは名前空間を使用してウィンドウスコープの外にjQueryを配置しますが、使用するライブラリの数がかなり多いので意味があります。全体として、誰もまだJSのグローバル変数を避けるべき理由は何もありません。なぜなら、それらは他のスクリプトによって簡単に上書きされてしまい、問題が発生する可能性があるからです。だから一般的にそれについて過度に耳を傾けることなく、慎重にするのが理にかなっています。 –

+1

グローバルでの他の問題は、グローバルであることです。何かを読む/変更する/壊す/変更する/一般的に混乱させることができます。これは、サーバー側Webアプリケーションのビューに直接SQLクエリを埋め込むべきではないという概念に似ています。基本的にグローバルは関心事の分離を破ります – Raynos

3

なぜ名前空間が悪いのか分かりません。私が気づいていないJavaScript固有の名前空間の定義がない限り。

私は現在、小さなライブラリに取り組んでおり、すべてが1つのトップレベルオブジェクト(名前空間?)で囲まれています。私はウィンドウや内在型に何も置かない。私の図書館から何かが必要な場合は、kiloオブジェクトで利用できます。

この「名前空間」を持つことは良いです練習私は私のライブラリのメソッドを呼び出している場合私は非常に迅速に知っているように。 window.alertメソッドをオーバーライドする必要はありません。これは、ページにロードされた別のライブラリとぶつかる可能性があります。カスタマイズされたバージョンにはkilo.alertを使用してください(これは実例ですが、それがポイントになることを願っています)。

+0

ライブラリからメソッドを呼び出すかどうかを知るには、そのライブラリによって公開されているオブジェクトとトークンを操作するだけでよいのかどうかを知るために '名前空間'は必要ありません。 – Raynos

+4

私が必要とするのは、名前空間の明確な定義です。 JavaScriptにはJavaScriptはありませんが、実際には言語の一部であるように、その話をしています。本当に、私は自分のライブラリに親オブジェクトを使用しています。 JavaScriptでは名前空間は実際には問題ではありません。ここで名前空間と呼ばれるものさえも、実際にはオブジェクトのチェーンに過ぎません。 – kiswa

1

JavaScriptで "名前空間は、" 実際には名前のプロパティを持つオブジェクトです。他のオブジェクト指向言語(すなわちC++、C#の、など)で、私はあなたが次のことをしたいとは思わない:

のC# -

public static class MyAppName {} 
public static class MyArea {} 
public static class MySubArea {} 

public static class Test { 
    public string Property1 { get { return "test"; }} 
} 

あなたは

MyAppName.MyArea.MySubArea.Test.Property1; 

を持つことができるだけので、だから、基本的にJSは実際に名前空間をサポートしていないので、人々は名前空間をシミュレートするためのハックを発明しました。

myAppSpace.mySubArea.myObject = blah... 
+2

"現実の世界"を参照して、あなたの言いたいことをするための他の言語のコードを含めることは、一般的に悪い考えです。 –

+0

@JaredFarrish私は彼が、この「名前空間」の概念がC#のような別の言語に移植されたときにも、醜いばかげたコードを生成することを説明しようとしていると思います。 – Raynos

+0

あなたはおそらく正しいでしょう... :) –

関連する問題