2011-01-23 13 views
4

私は、複数のモジュールを持つJSライブラリを構築しようとしています。ライブラリをLibraryと呼び、2つのモジュールをOneとTwoと呼びます。エンドユーザーが2つの異なる方法でライブラリを呼び出すことができるようにするために私が欲しい:基本的にオプションのjavascriptライブラリの名前空間

Library.One.somefunction(params) 

または

somefunction(params) 

私はエンドユーザーに名前空間を含むのオプションを提供したい、またはない。これを行う良い方法はありますか?また、私はライブラリのミニバージョンを提供したい場合、これを行う良い方法がありますか?このライブラリは、Node.jsで終わる可能性のあるものです。今は自分で使うつもりですが、将来的に共有可能なプロジェクトに入るのが難しくないようにデザインしたいと思います。

あなたが私に指摘することができる参照はすばらしいでしょう、ありがとう!

答えて

1

よく、私はあなたが「良い方法」を意味するかどうかわかりません。
まず、ネームスペースの目的は、関連する変数を収集し、パブリック名前空間の周りに散らばらないようにすることです。 は個人的に私は、このようなものを使用することはありませんが、あなたはあなたの名前空間のオブジェクトをループ可能性があり、窓に取り付けます:

 
for(var i in Namespace) 
    if(Namespace.hasOwnProperty(i)) 
     window[i] = Namespace[i]; 
2

「名前空間」オプションを作るの背後にある基本的な考え方は、window対象であるグローバルスコープに機能を割り当てることです:

window.somefunction = Library.One.somefunction; 

あなたが他の言語に似た働きinclude関数を書くことができます。必要に応じて

var include = function (library, p) { 
    if (!p) { 
     for (var prop in library) { 
      if (library.hasOwnProperty(prop)) { 
       window[prop] = library[prop]; 
      } 
     } 
    } else { 
     window[p] = library[p]; 
    } 
}; 

がそれからちょうど、実行します。

include(Library.One); 

または使用の特定の機能のみ:

include(Library.One, 'somefunction'); 

警告:ドット表記(One.somefunction)なしで機能を実行

  1. thisキーワードがwindowなくLibrary.Oneを参照します。 thisをまったく使用しないと、問題はありません。あなたが関数の間に共有するデータを持っているなら、あなたはthisの代わりにクロージャのスコープを使用して行うことができます。

    var Library = {}; 
    
    (function() { 
        // I'm a closure, I have local scope 
        var sharedData = "I'm shared but private to this scope"; 
    
        Library.One = {}; 
    
        Library.One.funcOne = function() { 
         alert(sharedData); 
        }; 
    
        Library.One.funcTwo = function() { 
         sharedData += "!"; 
        }; 
    
    })(); 
    
  2. 他の人があなたの方法をグローバルにするためにではない、よくアドバイスがあります。これは、いったんグローバルになると、すべてのファイルにとってグローバルであり、したがって他のコードと競合する可能性があるからです。あなたができることは、上記のimport関数を変更して新しいオブジェクトを作成し、そのオブジェクトにすべてを代入してから返すことです。そして、特定のライブラリへのショートカットを行うことができます必要なファイル:

    (function() { 
        var _ = include(Library.One); // This stays within this scope 
        _.somefunction(); 
    })(); 
    
+0

のみのブラウザでは、名前 'window'を提供しています。代わりに 'global'を使用してください。 – erjiang

+0

@erjiang、ありがとう、node.jsというタグが付いていたのを忘れてしまった。それがノードであることを見ると、モジュールシステムのせいでほとんどのものは無関係です。 –

+0

'import'は予約語です。http://www.crockford.com/javascript/survey.html – galambalazs

0

あなたはかなり簡単にこれを行うことができますが、あなたは、特定のすべてのメソッドにグローバルプロパティを作成したいですか?

あなたはこの(非常に単純化された)のようにそれを実装することができます:あなたは本当にこのようなグローバルな名前空間を汚染したい場合、私は疑問に思うだろう

(function(window, undefined) { 

    // Your code setting up namespaces 
    var Library = {One:{},Two:{}}; 

     // function for adding library code to both namespaces. 
     // Could be modified to accept an Array of functions/names 
    function addToLibraryOne(id, fn) { 
     window[id] = Library.One[id] = fn; 
    } 

     // add a function 
    addToLibraryOne("somefunction", function(params) { 
      // function code 
    }); 

    window.Library = Library; 

})(window); 

少なくとも、私はglobalプロパティをオプションにしてから、そのオプションが選択されている場合は、そのプロパティを追加するだけです。

0

は、私はこれがdownvotedてしまうかもしれません(これについて間違っているかもしれないが、私はこれをしたいです

1)ネームスペースを使いたい
2)ネームスペースなしでネームスペース機能にアクセスしたいと思っています。

では、基本的に2は「ネームスペースは必要ありません」です。

実装するには、名前空間にルーティングする関数群をグローバルに定義することができますが、なぜ名前空間を先頭に入れるのですか?

+0

アイデアは私の開発と典型的なライブラリに名前空間を使いたいだけでなく、名前空間を使わないというオプションも与えたいということです。 JavascriptでMath.sin(3)を考えてみましょう。名前空間なしでライブラリをインポートすることを選択した場合、誰かがMath.sin(3)の代わりにsin(3)と言うだけでいいですね。それがアイデアです。 – Geoff

0

もう1つは、関数とオブジェクト、モジュール内のすべてのものをグローバルスコープに入れたいということです。もちろん完全に可能ですが、ベストプラクティスに対してはいくぶん忌まわしいことです。

var Library = {}; 

をして、あなたのモジュールでそれを移入開始:

最初の部分については、ちょうど世界的にあなたのライブラリの名前空間を宣言

Library.One = {}; 
Library.Two = {}; 

、その後、それらのモジュールに機能の追加を開始。

(function($) { 
    var $.froobString = function(s) { .... }; 
    ...etc... 
})(Library.One); 

(ここで私は$としてLibrary.Oneに渡した自己実行匿名関数としてそれをやった。)

をグローバルにすべてのことを変換するには、このようなルーチンを持っている:

var convertToGlobals = function(module) { 
    for (name in module) { 
    window[name] = module[name]; 
    } 
}; 
convertToGlobals(Library.One) 

しかし、もう一度私はそれに反対したいと思います。

5

あなたはCommonJSモジュールシステムを活用することができのNode.jsを使用している場合。 (誰かがそれを使用して...)

math.js(ライブラリ)

exports.add = function() { 
    for (var i = arguments.length; i--;) { 
     sum += arguments[i]; 
    } 
    return sum; 
}; 

program.js

var MyMath = require('math'); 
console.log(MyMath.add(1, 2)); // 3 

// ... in different ways 

var add = require('math').add; 
console.log(add(1, 2)); // 3