最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

學習JavaScript設計模式之觀察者模式

 更新時間:2020年04月22日 09:12:06   作者:奮飛  
這篇文章主要為大家介紹了JavaScript設計模式中的觀察者模式,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

一、定義

觀察者模式(發(fā)布-訂閱模式):其定義對象間一種一對多的依賴關系,當一個對象的狀態(tài)發(fā)生改變時,所有依賴于它的對象都將得到通知。
在JavaScript中,一般使用事件模型來替代傳統(tǒng)的觀察者模式。
好處:

  • (1)可廣泛應用于異步編程中,是一種替代傳遞回調函數(shù)的方案。
  • (2)可取代對象之間硬編碼的通知機制,一個對象不用再顯示地調用另外一個對象的某個接口。兩對象輕松解耦。

二、DOM事件–觀察者模式典例

需要監(jiān)控用戶點擊document.body的動作,但是我們沒有辦法預知用戶將在什么時間點擊。
所以,我們訂閱document.body上的click事件,當body節(jié)點被點擊時,body節(jié)點便向訂閱者發(fā)布這個消息!

document.body.addEventListener("click", function() {
 console.log(1);
}, false);

// 可以多個訂閱者
document.body.addEventListener("click", function() {
 console.log(2);
}, false);

doucment.body.click();

某網(wǎng)站有header頭部、nav導航、消息列表等模塊。這幾個模塊的渲染都需要獲取用戶登陸信息。

(1)一般寫法:

$.ajax({
 url: './login',
 type: 'post',
 contentType: 'application/json',
 dataType:'json',
 success: function(data) {
 if(data.status === "success") {
  // 登錄成功,渲染header、nav
  header.setInfo(data.headerInfo);
  nav.setInfo(data.navInfo);
 }
 }
});

(2)使用觀察者模式,很輕松解耦!

$.ajax({
 ...,
 success: function(data) {
 if(data.status === "success") {
  // 登錄成功,發(fā)布登陸成功消息
  login.trigger("loginsuccess", data);
 }
 }
});

var header = (function() {
 // 監(jiān)聽消息
 login.listen("loginsuccess", function(data){
 header.setInfo(data.headerInfo);
 });
 return {
 setInfo: function(data) {
  console.log("設置header信息");
 }
 };
})();

var nav = (function() {
 login.listen("loginsuccess", function(data){
 nav.setInfo(data.navInfo);
 });
 return {
 setInfo: function(data) {
  console.log("設置nav信息");
 }
 }
})();

三、通用觀察者模式

/*
 * 示例:
 * Event.create("namespace1").listen('click', function(a){
 * console.log(a);
 * });
 * Event.create("namespace1").trigger("click", 1);
 */
var Event = (function() {
 var global = this,
 Event,
 _default = 'default';

 Event = function() {
 var _listen,
  _trigger,
  _remove,
  _slice = Array.prototype.slice,
  _shift = Array.prototype.shift,
  _unshift = Array.prototype.unshift,
  namespaceCache = [],
  _create,
  find,
  each = function( ary, fn) {
  var ret;
  for(var i = 0, l = ary.length; i < l; i++) {
   var n = ary[i];
   ret = fn.call(n, i, n);
  }
  return ret;
  };
 // 訂閱
 _listen = function(key, fn, cache) {
  if(!cache[key]) {
  cache[key] = [];
  }
  cache[key].push(fn);
 };
 // 移除訂閱
 _remove = function(key, cache, fn) {
  if(cache[key]) {
  if(fn) {
   for(var i = cache[key].length; i >=0; i++) {
   if(cache[key][i] === fn) {
    cache[key].splice(i, 1);
   }
   }
  }else {
   cache[key] = [];
  }
  }
 };
 // 發(fā)布
 _trigger = function() {
  var cache = _shift.call(arguments),
  key = _shift.call(arguments),
  args = arguments,
  _self = this,
  ret,
  stack = cache[key];
  if(!stack || !stack.length) {
  return;
  }
  return each(stack, function() {
  return this.apply(_self, args);
  });
 };
 // 創(chuàng)建命名空間
 _create = function(namespace) {
  var namespace = namespace || _default;
  var cache = {},
  offlineStack = [], // 離線事件
  ret = {
   listen: function (key, fn, last) {
   _listen(key, fn, cache);
   if (offlineStack == null) {
    return;
   }
   if (last === 'last') {
    offlineStack.length && offlineStack.pop()();
   } else {
    each(offlineStack, function () {
    this();
    });
   }
   offlineStack = null;
   },

   one: function (key, fn, last) {
   _remove(key, cache);
   this.listen(key, fn, last);
   },

   remove: function(key, fn, last) {
   _remove(key, cache, fn);
   },

   trigger: function() {
   var fn,
    args,
    _self = this;
   _unshift.call(arguments, cache);
   args = arguments;
   fn = function() {
    return _trigger.apply(_self, args);
   };
   if(offlineStack) {
    return offlineStack.push(fn);
   }
   return fn;
   }
  };

  return namespace ? (namespaceCache[namespace] ? namespaceCache[namespace] : namespaceCache[namespace] = ret) : ret;
  };

 return {
  create: _create,
  one: function(key, fn, last) {
  var event = this.create();
  event.one(key, fn, last);
  },
  remove: function(key, fn) {
  var event = this.create();
  event.remove(key, fn);
  },
  listen: function(key, fn, last) {
  var event = this.create();
  event.listen(key, fn, last);
  },
  trigger: function() {
  var event = this.create();
  event.trigger.apply(this, arguments);
  }
 };
 }();
 return Event;
})();

希望本文所述對大家學習javascript程序設計有所幫助。

相關文章

  • JavaScript函數(shù)重載操作實例淺析

    JavaScript函數(shù)重載操作實例淺析

    這篇文章主要介紹了JavaScript函數(shù)重載操作,結合一次面試經(jīng)歷分析了JavaScript函數(shù)重載相關原理、用法及操作注意事項,需要的朋友可以參考下
    2020-05-05
  • json的結構與遍歷方法實例分析

    json的結構與遍歷方法實例分析

    這篇文章主要介紹了json的結構與遍歷方法,結合具體實例形式分析了json常見的簡單與復雜結構表示方法,以及具體的遍歷操作實現(xiàn)技巧,需要的朋友可以參考下
    2017-04-04
  • JS使用正則表達式實現(xiàn)常用的表單驗證功能分析

    JS使用正則表達式實現(xiàn)常用的表單驗證功能分析

    這篇文章主要介紹了JS使用正則表達式實現(xiàn)常用的表單驗證功能,結合實例形式分析了JS基于正則表達式的表單驗證功能原理、實現(xiàn)技巧與操作注意事項,需要的朋友可以參考下
    2020-04-04
  • JS實現(xiàn)的透明度漸變動畫效果示例

    JS實現(xiàn)的透明度漸變動畫效果示例

    這篇文章主要介紹了JS實現(xiàn)的透明度漸變動畫效果,涉及javascript響應鼠標事件針對頁面元素屬性動態(tài)操作相關實現(xiàn)技巧,需要的朋友可以參考下
    2018-04-04
  • javascript實現(xiàn)懸浮跟隨框緩動效果

    javascript實現(xiàn)懸浮跟隨框緩動效果

    這篇文章主要為大家詳細介紹了javascript實現(xiàn)懸浮跟隨框緩動效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 淺談JS中json數(shù)據(jù)的處理

    淺談JS中json數(shù)據(jù)的處理

    下面小編就為大家?guī)硪黄獪\談JS中json數(shù)據(jù)的處理。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-06-06
  • js event事件的傳遞與冒泡處理

    js event事件的傳遞與冒泡處理

    與Netscape相反,IE中的事件傳遞方向是從事情發(fā)生的對象開始,然后依次由該對象向所在的父節(jié)點傳遞。
    2009-12-12
  • js實現(xiàn)登錄時記住密碼的方法分析

    js實現(xiàn)登錄時記住密碼的方法分析

    這篇文章主要介紹了js實現(xiàn)登錄時記住密碼的方法,結合實例形式分析了JavaScript基于cookie實現(xiàn)存儲登錄密碼相關操作技巧,需要的朋友可以參考下
    2020-04-04
  • layui.use模塊外部使用其內(nèi)部定義的js封裝函數(shù)方法

    layui.use模塊外部使用其內(nèi)部定義的js封裝函數(shù)方法

    今天小編就為大家分享一篇layui.use模塊外部使用其內(nèi)部定義的js封裝函數(shù)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-09-09
  • Bootstrap筆記—折疊實例代碼

    Bootstrap筆記—折疊實例代碼

    本篇文章主要介紹了Bootstrap筆記—折疊實例代碼,詳細的介紹了折疊效果實例,包括一組多組等,非常具有實用價值,需要的朋友可以參考下。
    2017-03-03

最新評論

雷波县| 高要市| 安丘市| 延边| 噶尔县| 阜康市| 叶城县| 岗巴县| 中宁县| 嘉黎县| 福泉市| 盐亭县| 将乐县| 海门市| 克山县| 时尚| 沙湾县| 上思县| 南康市| 崇阳县| 汤阴县| 铜鼓县| 太原市| 桐梓县| 庆元县| 和政县| 舒城县| 紫阳县| 长岭县| 松潘县| 芦溪县| 洱源县| 丰镇市| 玉山县| 沙雅县| 长沙市| 五常市| 云梦县| 南涧| 五指山市| 萝北县|