行ごとの説明は次のとおりです(分割するためだけにヘッダーを付けています):
セットアップ:
// Create an anonymous function expression taking `NAMESPACE` as a parameter.
// Likely the *real* namespace will be passed to the function at the end
// with ... })(realnamespacetomodify);
(function(NAMESPACE) {
// Create the new part of the namespace. Note that we are editing a reference
// so really this change happens on whatever object was passed in.
NAMESPACE.nav = {};
// Create a local pointing to this new sub-namespace. Probably just for
// convenience, also possibly for portability (if the name is used in closures,
// then those closures don't need to refer to NAMESPACE directly).
var nav = NAMESPACE.nav,
モジュール定義:
// While nav refers to an object likely in global scope, nav itself can
// never be referred to from global scope because it is a local here.
// These variables are local here. They can never be referred to by global scope.
_isNavOpen = false,
_inner = document.getElementById('inner-wrap');
// These variables, added to nav, can be accessed using the object that
// nav refers to in global scope (see the end).
nav.CLASS = 'js-nav-open';
...
// This function is also added to nav, therefore it can be accessed outside
nav.toggle = function(event) {
...
// This reference to _isNavOpen resolves because this function
// is a closure, and binds variables outside its scope
// to the function itself. So even though _isNavOpen can't be
// accessed globally, it can be accessed here, making it like
// a private member of this namespace.
if(_isNavOpen && $('html').hasClass(nav.CLASS)) {
// nav is also bound by the closure and can be accessed here
nav.close();
} ...
};
グローバル空間で使用:
}(PROJECT_NAME));
console.log(PROJECT_NAME.nav.CLASS); // "js-nav-open"
console.log(PROJECT_NAME.nav.toggle); // Function object
モジュールパターンです。いくつかの理由で使用されます。
- コードの移植性(モジュール内のグローバル オブジェクトを参照しない)
- スコーピング(不要な変数をグローバル名前空間に割り当てないようにする)
- 可視性(プライベート アクセス変数の非表示)
最初の 3 行自体 (元の質問)については、直接参照できますが、コードの移植性PROJECT_NAME
を支援するために設定されているようです。無名関数自体が実際のオブジェクト ( ) を決して指していないことに気付くでしょう。つまり、この部分をコピーして貼り付け、その参照を 1 か所だけ変更できます。PROJECT_NAME
他の回答ではスコープについて言及していますが、これも重要ですが、既存のグローバル変数を直接参照しない理由など、このコードのすべての利点を説明しているわけではありません。スコープを隠す利点自体は、パターンのこの部分で実現されます。
(function() {
... // Anything set here is local, not global.
})();