閉包實(shí)現(xiàn)面向?qū)ο笤O(shè)計(jì)
閉包的思想是: 一個(gè)函數(shù)想用一個(gè)引用一個(gè)外部變量,但是有不想讓這個(gè)變量暴露在全局環(huán)境中,那么就使用閉包。閉包一般有兩種使用形式,一個(gè)是立即執(zhí)行的閉包,一種是用時(shí)執(zhí)行的閉包。兩種有和區(qū)別呢?
立即執(zhí)行的閉包,用于全局創(chuàng)建一個(gè)閉包對(duì)象
用時(shí)執(zhí)行的閉包,可用于全局創(chuàng)建多個(gè)閉包對(duì)象
//立即執(zhí)行的模式
var matchEmail = (function() {
var regx = /^\w+(\.\w+)*@\w+\.\w{2,3}(\.\w{2,3})?$/;
return function(email) {
return regx.test(email);
}
})();
console.log(matchEmail('535.fu@qq.com'));
//用時(shí)執(zhí)行的模式
var matchEmail2 = function() {
var regx = /^\w+(\.\w+)*@\w+\.\w{2,3}(\.\w{2,3})?$/;
return function(email) {
return regx.test(email);
}
}
var matchEmail2 = matchEmail2();
console.log(matchEmail('535.fu@qq.com'));
兩者有啥區(qū)別呢?容易看出,用時(shí)執(zhí)行模式,每次在創(chuàng)建一個(gè)新的matchEmail2時(shí)候,都會(huì)新建一個(gè)閉包,和創(chuàng)建一個(gè)新的 regx
立即執(zhí)行啥時(shí)候用呢? 一般是在封裝的遍歷在函數(shù)引用中都是有同一個(gè)時(shí),如果不同情況需要使用多個(gè),那么使用 用時(shí)執(zhí)行
很顯然,我們?nèi)绻胍獎(jiǎng)?chuàng)建一個(gè)對(duì)象系統(tǒng)的話,需要用用時(shí)執(zhí)行模式
var Events = function() {
var handlers = {};
var subscribe = function(type, handler) {
if (!handlers[type]) {
handlers[type] = [];
}
handlers[type].push(handler);
//存儲(chǔ)當(dāng)前這個(gè)handler是否被訂閱
var isSubscribed = true;
//每次執(zhí)行一個(gè)訂閱函數(shù),返回一個(gè)取消訂閱回調(diào),只要使用這個(gè)函數(shù),那么就取消
return function unsubscribe() {
if (!isSubscribed) return; //防止多次執(zhí)行
isSubscribed = false;
const index = handlers[type].indexOf(handler);
handlers[type].splice(index, 1);
}
}
function dispatch(type) {
if (handlers[type]) {
for (let i = 0; i < handlers[type].length; i++) {
handlers[type][i]();
}
}
}
//閉包對(duì)象系統(tǒng),返回一個(gè)對(duì)象
return {
subscribe,
dispatch
}
}
//創(chuàng)建一個(gè)event對(duì)象
var event = Events();
//創(chuàng)建另外一個(gè)event對(duì)象
var event1 = Events();
var unSubscribe = event.subscribe('click', function() {console.log('event click')});
event1.subscribe('click', function() {console.log('event1 click')});
event.dispatch('click');
event1.dispatch('click');
unSubscribe();
event.dispatch('click');
上面創(chuàng)建的兩個(gè)對(duì)象 event event1 互不干擾
利用閉包創(chuàng)建對(duì)象系統(tǒng)的話,利用閉包封裝想用的局部變量,然后返回一個(gè)對(duì)象,對(duì)象里面是向外提供的接口
tips:上面的訂閱一個(gè)函數(shù),然后返回一個(gè)取消點(diǎn)閱函數(shù),也是一種非常不錯(cuò)的發(fā)布 取消點(diǎn)閱模式中的編程思想哦,利用閉包,在訂閱的時(shí)候就封閉了訂閱時(shí)的函數(shù),那么取消點(diǎn)閱的時(shí)候,就一定能訪問到這個(gè)函數(shù)