web-dev-qa-db-ja.com

単純なJavascript SPAでグローバル変数の使用を回避するにはどうすればよいですか?

JavaScriptを学ぶために、私は単純な単一ページのアプリケーションを構築しています。これは、いくつかの基本設定を処理し、いくつかの動作を実行するだけでよい基本的なスライドショーアプリです。したがって、私のコードの基本的な構造は次のとおりです。

var settings = { ... };

function initStartPage() { ... };
function initSlideshow() { ... };
function settingsHandler() { ... };
function doSomething() { ... };

...各関数は、変数settingsに含まれるデータにアクセスし、場合によっては変更する必要があります。

私は、グローバル変数や不必要に複雑な構成を使用せずにこれを構造化する方法に少し困惑しています。私はJavaまたはCでのプログラミングに慣れています。小さなアプリの変数はメイン関数で快適に使用できます。グローバルスコープを取り除くために考えられる唯一の解決策は、単純なネームスペースです。

var namespace = {};
namespace.settings = { ... };

namespace.initStartPage = function() { ... };
namespace.initSlideshow = function() { ... };
namespace.settingsHandler = function() { ... };
namespace.doSomething = function() { ... };

だから私の質問は:

1。これは、多くのパーツが同じデータにアクセスするシステムの合理的な解決策ですか?

2。より良い、より標準的なソリューションはありますか?

3
jdd

はい、PUBLIC(名前空間)変数が必要な場合は、これが標準的なアプローチだと思います。しかし、プライベートな名前空間変数を作成するには、通常のアプローチはクロージャーを使用することです( プライベートデータにクロージャーを使用する例

または、学習しているため、プライベートデータメンバーを直接サポートする TypeScript の使用を検討してください。

3
Lewis Pringle

@Lewis Pringleが言ったように、 closure は、グローバル名前空間の汚染を最小限に抑える典型的な方法です。これは、いわゆる [〜#〜] iife [〜#〜] -即座に呼び出される関数式の観点から来ています。

これらの構築ブロックで:

  • プライベートスペースを確保するためのクロージャー
  • すぐに呼び出される関数

javaScriptで 明らかにmodule パターンにアクセスします。

const app = (()=>{
  const init = ()=>{
    alert("hi");
  };
  return { init: init};
})()

app.init();

重要なのは、appが参照を保持している解析の直後に、無名関数が定義され、呼び出されていることです。この無名関数内のすべては、基本的にこの関数にプライベートです。パブリックへの唯一のインターフェースは、返されるオブジェクトを介して行われます。ここで、initキーは、無名関数のスコープで定義された「プライベート」init関数を指します。

appはオブジェクトへの参照を保持し、オブジェクトはこのスコープにアクセスできます。

そこから、依存性注入のようなものを構築できます。即時に呼び出される関数はパラメーターを受け取り、クロージャーのスコープに渡すことができます。

const c => ((a,b)=>{ ... })(a,b)

以前に宣言されたaおよびbcに「注入」します。

2
Thomas Junk