用閉包實(shí)現(xiàn)面向?qū)ο笙到y(tǒng)

閉包實(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ù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容