函數執行造成的私有上下文,即能保護裏面的私有變量不受外界干擾,也能在當前上下文中保存一些信息(前提:造成的上下文不銷燬),上下文中的這種保存和保護機制,就是閉包機制javascript
在這個上下文中會有一些私有的變量AO(XX),這些私有的變量和外界的變量不會衝突(互不影響)java
某些狀況下,上下文中的某些內容被外界佔用後,當前上下文並不會出棧銷燬,這樣就會把上下文中的一些信息儲存起來編程
A/B
共同開發一個頁面,最後要把代碼合併在一塊兒,爲了防止全局變量的衝突污染,咱們建議每一個開發者,都把本身的代碼放置到一個閉包中(自執行函數執行便可,這樣就是私有的上下文)保護起來// A的代碼
(function anonymous() {
/* 自執行函數執行,會造成一個私有的上下文,在這裏聲明+定義的變量或者函數都是私有的 */
var x = 100,
y = 200;
function func() {
// ...
}
})();
// B的代碼
~ function anonymous() {
// console.log(anonymous); //=>函數自己
//=>匿名函數設置的函數名只能在函數裏面應用,函數外面是沒法訪問的
var x = 200,
n = 0;
function func() {
// ...
}
function handled() {
// ...
}
}();
// console.log(anonymous); //=>Uncaught ReferenceError: anonymous is not defined
複製代碼
jQuery
.../* JQUERY源碼一瞥 */
// typeof window !== "undefined" ? window : this 瀏覽器端window是存在的,因此爲window
(function (global, factory) {
"use strict";
// => global===window
// => factory===function (window, noGlobal){...}
factory(global);
})(window, function (window, noGlobal) {
// JQUERY的源碼
});
//=> 利用閉包的機制,把JQ源碼看成自執行函數的形參傳給函數,完成執行
複製代碼
此時咱們發現一個問題:每一個人的代碼都獨立了,那咱們每一個人都會用到的公共方法,難道也要都單獨寫一遍?設計模式
有此需求,必然得有解決辦法:瀏覽器
需求:咱們須要把某一個閉包(私有上下文)中的值暴露到外面閉包
這種辦法雖然能夠實現,可是也會存在衝突,若是咱們每個版塊都須要暴露更多的方法,同時都基於這種方法暴露到全局對象GO上,也可能致使方法之間的衝突函數
(function anonymous() {
function queryURLParams() {
// ...
}
function sum() {
// ...
}
// 想暴露到外面使用,能夠暴露到全局上(賦值給全局對象GO =>window)
window.queryURLParams = queryURLParams;
window.sum = sum;
})();
queryURLParams(); //=>window.queryURLParams()
複製代碼
每個版塊暴露到全局下只有一個變量而已,全部須要供別人調取的方法都在對象中(這樣暴露一個或者多個都無所謂)性能
- 避免了全局變量的污染,也同時實現了不一樣閉包之間方法的公用性
var utils = (function anonymous() {
// queryURLParams:獲取URL地址參數信息
function queryURLParams() {
// ...
}
// sum:實現任意數求和
function sum() {
// ...
}
// 把須要供外面訪問的變量和方法,賦值給一個對象,最後返回(外層基於VAR utils定義變量來接收便可)
return {
queryURLParams: queryURLParams,
sum: sum
}; //=>return AAAFFF000;
})();
// console.log(utils); //=>{queryURLParams:函數,sum:函數}
utils.queryURLParams();
utils.sum();
複製代碼
utils對象中包含了須要供別人調取使用的方法;此時咱們把utils稱之爲「命名空間」,而對象就是一個空間,空間中包含了當前版塊中的內容,或者是把當前版塊中的內容按照命名空間進行了分組,每個分組都是一個單獨的個體 ui