2

次のモジュールがあり、両方とも拡張 可能な複数のファイルに分割されているとしますskillet

File1.js:

(function(){
 var privateVar1 = 0;

 var privateFunction1 = function() {
  //function definiton
 };

 skillet.fry() = function() {
  //fry it
  //matchbox.light();
 };

})(window.skillet = window.skillet || {});

File2.js:

(function(){
 var privateVar2 = 0;

 var privateFunction2 = function() {
  //some private function 
 };

 skillet.grillIt = function() {
  //grill It
  //matchbox.strike(); <-- Shared with File1.js
 };

})(window.skillet = window.skillet || {});

またはにバインドされることなくmatchbox、2つのモジュールで共有できるような共有変数/オブジェクトを持つことは可能ですか?つまり、の可視性はFile1.jsとFile2.jsに対してのみであり、他の場所からアクセスできないようにする必要があります。それが可能かどうかは疑問ですが、JavaScriptでそのような動作を実現する方法はありますか?そうでない場合、この点で使用するベストプラクティスは何ですか?window.matchboxwindow.skillet.matchboxmatchbox

(これは、関連するモジュールのセット間でイベントバスを共有し、そのバスをグローバルに公開しないようなものです)

4

2 に答える 2

3

いいえ。

「プライベート」変数は、関数が宣言されたスコープのためにのみJSで機能します。まったく異なるスコープで宣言された関数とそのスコープを共有する方法はありません。スコープは、一度作成されると、関数の変更できないプロパティです。

これが、この種のことが通常_fooスタイルプロパティで行われる理由です。

skillet._matchbox = { strike: function() { ... } };

アンダースコアプレフィックスは「内部」の規則であり、それを台無しにしないためのヒントとして機能します。


matchboxただし、すべての場合において、matchbox元の範囲を抜け出す方法を提供することを意味しますが、どのように渡すかについて創造的になることもできます。おそらくのようにskillet.extend、マッチボックスをその引数に渡すメソッドを作成しますか?

(function() {
  var matchbox = { strike: function() { ... } }
  window.skillet = {
    extend: function(fn) {
      fn(matchbox);
    }
  };
})();

skillet.extend(function(matchbox) {
  var privateVar2 = 0;
  var privateFunction2 = function() {};

  skillet.grillIt = function() {
    //grill It
    matchbox.strike();
  };
}

これにより、matchbox元のスコープの外で制御された方法で使用できます。しかし、それはまた、誰もがそれを手に入れることを可能にしますmatchbox

var stolenMatchbox;
skillet.extend(function(matchbox) {
  stolenMatchbox = matchbox;
});
while (stolenMatchbox.count > 0) { stolenMatchbox.strike(); }
alert("Now you are outta matches, sucker!");
于 2012-07-19T19:48:07.640 に答える
2

すでにコードを複数のファイルに分割しているので、require.jsのようなモジュールローダーの使用を検討することができます。マッチボックスの3番目のモジュールを定義し、それを上記の例の2つのスキレットへの引数として渡すことができます。このアプローチでは、ウィンドウを介してマッチボックスをグローバルに公開する必要はありません。

require.jsを含むFile1.jsは次のようになります。

define(['matchbox'], function(matchbox){
(function(){
    var privateVar1 = 0;

    var privateFunction1 = function() {
     //function definiton
    };

    skillet.fry() = function() {
       //fry it
       matchbox.light();
    };

 })(window.skillet = window.skillet || {});
});

matchbox.jsは次のようになります。

define([], function() {
  function light() {
     //light implementation
  }

  function strike() {
     //strike implementation
  }

  return {
     light: light,
     strike: strike
  }
}
于 2012-07-19T19:56:26.423 に答える