web-dev-qa-db-ja.com

グローバル変数が悪い習慣と見なされるのはなぜですか?

JavaScriptでグローバル変数を使用しないように警告が表示され続けますが、人々がそれを言っている唯一の理由は、グローバル名前空間を詰まらせているためだと思われます。すべての変数を1つの大きなオブジェクトに入れることで、これが簡単に修正されると想像できます。質問は次のとおりです。便利さ以外にグローバル変数を使用しない他の理由はありますか?それらに関連するパフォーマンスまたは互換性の問題はありますか?

32
user1318416

グローバルな名前空間を乱雑にし、ローカル変数よりもルックアップが遅くなります。

まず第一に、多くのグローバル変数を持つことは常に悪いことです。どこかで変数を宣言したことを忘れて、どこかで誤って再宣言するのは簡単だからです。最初の変数がローカルである場合、問題はありません。グローバルな場合は、上書きされただけです。これは、暗黙のグローバルに入るとさらに悪化します(例:someVar = someValuevarキーワードでsomeVarを宣言せずに)。

第二に、グローバル変数は、Javascriptがローカル変数よりも「見つける」のに時間がかかります。速度の違いはそれほど大きくありませんが、doesは存在します。

グローバルが悪い習慣と見なされる理由の詳細な説明とより詳細な説明については、 このページ をチェックしてください。

36

グローバル変数は結合を大幅に増加させ、コードのスケーラビリティとテスト容易性を大幅に低下させます。グローバルの使用を開始したら、変数がどこでどのように変更されるかを知る必要があります(つまり、カプセル化を解除します)。世の中に出回っている文献や慣習のほとんどは、グローバルを使用する際のパフォーマンスの懸念が最も少ないと主張しています。

これは 理由の概要を説明する素晴らしい記事 グローバル変数が頭痛の種です。

12
undeniablyrob

スクリプトが非常に長く、多くの関数からこれらの変数を使用すると、グローバル変数の値がどこからでも変更される可能性があるため、デバッグ時間が長くなります。それらをすべてチェックする必要があります。

別のプログラマーがページに含まれる他のスクリプトからこの変数を変更すると、このシナリオはさらに苦痛になります。

5
Roberto Linares

一言で言えば、グローバル変数は次の問題(およびそれ以上)を引き起こします。

1)変数の命名の衝突-チームで作業していて、自分と同僚の両方がグローバルスコープで同じ変数名を使用している場合、最後に定義された変数が初期変数を上書きします。この明らかなことは壊滅的な結果をもたらす可能性があります。

2)セキュリティ-特にWebでは、すべてのユーザーがWindow(またはグローバル)オブジェクトにアクセスできます。グローバルスコープに変数を配置することにより、すべてのユーザーが変数を表示または変更できるようになります。

3)遅い-これは間違いなくごくわずかですが、まだ存在します。 JavaScript変数のルックアップが機能する方法は、JavaScriptエンジンが変数がルックアップされている現在のスコープでルックアップを行うことです。それが見つからない場合、次の親スコープでルックアップを行います。そこに見つからない場合は、その変数を探しているグローバルオブジェクトに到達するまで上方向を探し続けます。すべての変数がグローバルスコープにある場合、JavaScriptエンジンは常にすべてのスコープを通過して、最終的にグローバルスコープに到達して変数を見つける必要があります。

4
Tyler McGinnis

独自の名前空間/オブジェクト内にグローバル変数をラップしている限り、コード内でグローバル変数を使用しても問題はないはずです(自分のものではないスクリプトとの衝突を避けるため)

Javascriptでグローバル変数を使用する1つのアドバンテージがあり、javascriptが強力な型言語ではないという事実から派生しています。そのため、いくつかの複雑なオブジェクトを関数に引数として渡すと、それらのオブジェクトのすべてのインテリジェンス(関数スコープ内)を徹底的に失いますが、代わりにグローバルオブジェクトを使用すると、そのインテリジェンスが保持されます。そして、あなたが知性を持っているとき、それは実際にデバッグ時間を改善することができます(他の人が言ったこととは対照的に...)

私は個人的に非常に有用であり、それがコードに確実に含まれていることを発見しました。

(もちろん、ローカル変数とグローバル変数との間で常に適切なバランスを取る必要があります)

3
yoav barnea

基本的には、ページ上の任意のスクリプトからアクセスでき、同じスコープ内で名前を繰り返すことができるためです。そのため、多くのJavascriptエンジンがこのコードを使用しています。

(function(){
    var foo = 'foo',//Local
    bar = 'bar';//Local
    window.globalVar = foo + bar;//Global
})();
alert(foo);//Error
alert(bar);//Error
alert(globalVar );//'foobar'
1
Danilo Valente

作成したグローバル変数は、既存のウィンドウオブジェクトプロパティを上書きする場合があります。グローバル変数はグローバルコンテキスト、つまりウィンドウオブジェクトでアクセスしているためです。

0
Apoorv Nag