这篇文章主要为大家介绍了 JavaScript 设计模式中的观察者模式,对 JavaScript 设计模式感兴趣的小伙伴们可以参考一下
Javascript 是一种由 Netscape 的 LiveScript 发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如 Perl,遗留的速度问题,为客户提供更流畅的浏览效果。
一、定义
观察者模式(发布 - 订阅模式):其定义对象间一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。
在 JavaScript 中,一般使用事件模型来替代传统的观察者模式。
好处:
二、DOM 事件–观察者模式典例
需要监控用户点击 document.body 的动作,但是我们没有办法预知用户将在什么时间点击。
所以,我们订阅 document.body 上的 click 事件,当 body 节点被点击时,body 节点便向订阅者发布这个消息!
- document.body.addEventListener("click",
- function() {
- console.log(1);
- },
- false);
- // 可以多个订阅者
- document.body.addEventListener("click",
- function() {
- console.log(2);
- },
- false);
- doucment.body.click();
某网站有 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") {
- // 登录成功,发布登陆成功消息
- login.trigger("loginsuccess", data);
- }
- }
- });
- var header = (function() {
- // 监听消息
- 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] = [];
- }
- }
- };
- // 发布
- _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);
- });
- };
- // 创建命名空间
- _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 程序设计有所帮助。
来源: http://www.phperz.com/article/17/0224/267497.html