下面是一行一行地解釋(用頭只是爲了打破它):
設置:
// 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
這是一個模塊圖案。它用於以下幾個原因:
- 代碼的可移植性(不是指模塊內的全局對象)
- 作用域(避免分配不必要的增值經銷商向全局命名空間)
- 能見度(隱藏私人訪問變量)
至於前三行本身(您的原始問題),他們可能是直接參考PROJECT_NAME
,但它看起來像它已被設置爲幫助代碼可移植性。您會注意到匿名函數本身從未指向真實對象(PROJECT_NAME
)。這意味着您可以複製和粘貼這個部分,只在一個地方更改該參考。
另一個答案提到了範圍,雖然這也很重要,但它並沒有解釋這段代碼的所有好處,比如爲什麼它不直接引用現有的全局變量。
(function() {
... // Anything set here is local, not global.
})();
它既是擴展和外部對象(傳入),並創建一個局部變量。 – bfavaretto
你可以用'var nav = NAMESPACE.nav = {};'來代替。甚至可以省略局部變量,但這似乎是後面在代碼中方便地引用命名空間的方式。 –
@bfavaretto感謝您的評論 - 我可以看到你的意思(通過)。 – timmackay