1. 程式人生 > >javascript 設計模式 -- 發布/訂閱模式

javascript 設計模式 -- 發布/訂閱模式

length 內部 設計模式 name 不能 data lis 設計 class

直接上代碼:

index.html :

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>設計模式</title>
</head>
<body>
	<div id="box">
		<div>{{message}}</div>
	</div>
	<!--
	// 全局:
	// 低耦合,高內聚
	// 繼承:JS並沒有繼承這個概念(偽繼承),ajax沒有跨域這個概念一樣
	// 類式繼承、原型式繼承
	// 代碼重用高:方法解耦合高(獨立性)、方法盡量獨立和組合都能夠使用
	-->
	<script src="vue.js"></script>
	<script>
		/*// 類式繼承
		var father = function() { // 爸爸幹爸爸的活
			this.age = 50;
			this.say = function(){
				console.log(11);
			}
		}

		var child = function(){ // 兒子幹兒子的活
			this.name = "think";
			father.call(this); // call apply
		}

		var man = new child();
		man.say();*/

		// 原型式繼承
		var father = function(){
			//
		}

		father.prototype.a = function(){
			console.log(2);
		}

		var child = function(){
			//
		}

		// 子繼承父屬性
		child.prototype = new father();
		var man = new child();
		man.a();

		// jquery中所有方法都是可以連綴的 $(".box").html().css({"background":"yellow"})
		// new對象不能直接使用 局部對象所有對象外部都無法訪問 window.jQuery = window.$ = jQuery
		// 調用之後才 new

		new Vue({ // 
			el:"#box", // 元素
			data:{
				message:"hello",
				arr:[1,2,3],
				num:0
			},
			created: function(){ // vue構造函數
				var _this = this;
				setInterval(function(){ // 不屑分析
					_this.arr.push("DN"+(_this.num+1));
					// 操作內部數據時,不會整個渲染更新(DIFF算法:區分我們哪個地方有區別)
					_this.num += 1; // 動態數據追蹤,訂閱者模式

					// 值:更新的時候,元素是存在的,無需創建元素(document.createElement)
					// 數組增加:更新的時候,元素不存在,需要創建(document)
				},5000);
			}
		})

		//訂閱者模式
		// 每次都會輸出所有的信息
		/*var shoeObj = {};
		shoeObj.list = []; // 存放訂閱者

		shoeObj.listen = function(fn){ // 訂閱一次,增加數據一次
			shoeObj.list.push(fn); //訂閱消息添加到緩存列表
		}
		// 效果性的開發,只是基礎
		shoeObj.trigger = function(){ // 發布消息
			for(var i=0,fn;fn = this.list[i++];){
				fn.apply(this,arguments); // arguments
			}
		}

		// 訂閱
		shoeObj.listen(function(color,size){
			console.log(color);
			console.log(size);
		});

		shoeObj.listen(function(color,size){
			console.log("2" + color);
			console.log("2" + size);
		});

		shoeObj.trigger("紅色",20);
		shoeObj.trigger("黃色",20);*/

		// 修改後
		/*var shoeObj = {};
		shoeObj.list = []; // 存放訂閱者

		shoeObj.listen = function(key,fn){ // 訂閱增加一個名字,方便區分訂閱者信息
			if(!this.list[key]){
				shoeObj.list[key] = []; //訂閱消息添加到緩存列表
			}
			this.list[key].push(fn);
		}
		// 效果性的開發,只是基礎
		shoeObj.trigger = function(){ //根據訂閱者名字發布消息
			var key = Array.prototype.shift.call(arguments); //
			// arguments: 參數,取出消息類型的名稱
			var fns = this.list[key];

			// 如果沒有訂閱過該消息,則返回
			if(!fns || fns.length === 0){
				return;
			}

			for(var i=0,fn;fn = fns[i++];){
				fn.apply(this,arguments);
			}
		}

		// 訂閱
		shoeObj.listen("red",function(size){
			console.log(size);
		});

		shoeObj.listen("yellow",function(size){ // yellow改為動態參數,vuejs的動態更新出來一半
			console.log("2" + size);
		});

		shoeObj.trigger("red",40);
		shoeObj.trigger("yellow",40);*/


		// 封裝
		var event = {
			list:[], // 訂閱的人數是不固定的
			listen:function(key,fn){
				if(!this.list[key]){
					this.list[key] = [];// 清空
				}
			}
		}

		var shoeObj = {};
		shoeObj.list = []; // 存放訂閱者

		shoeObj.listen = function(key,fn){ // 訂閱增加一個名字,方便區分訂閱者信息
			if(!this.list[key]){
				shoeObj.list[key] = []; //訂閱消息添加到緩存列表
			}
			this.list[key].push(fn);
		}
		// 效果性的開發,只是基礎
		shoeObj.trigger = function(){ //根據訂閱者名字發布消息
			var key = Array.prototype.shift.call(arguments); //
			// arguments: 參數,取出消息類型的名稱
			var fns = this.list[key];

			// 如果沒有訂閱過該消息,則返回
			if(!fns || fns.length === 0){
				return;
			}

			for(var i=0,fn;fn = fns[i++];){
				fn.apply(this,arguments);
			}
		}

		// 訂閱
		shoeObj.listen("red",function(size){
			console.log(size);
		});

		shoeObj.listen("yellow",function(size){ // yellow改為動態參數,vuejs的動態更新出來一半
			console.log("2" + size);
		});

		shoeObj.trigger("red",40);
		shoeObj.trigger("yellow",40);

		var initEvent = function(){ // 讓所有普通對象都具有發布訂閱功能
			for(var i in event){ // 對象可以是多個
				obj[i] = event[i];
			}
		}

		var shoeObj = {};
		initEvent(shoeObj);

		shoeObj.listen("red",function(size){
			console.log(size);
		})

		shoeObj.trigger("red",40);

		// 取消訂閱
		event.remove = function(key,fn){
			var fns = this.list[key];
			if(!fns){
				return false;
			}
			if(!fn){
				fn && (fns.length = 0);
			}else{
				for(var i = fns.length-1;i>=0;i--){
					//
				}
			}
		}

		// RN
	</script>
</body>
</html>

.

javascript 設計模式 -- 發布/訂閱模式