layout: default
title: "JavaScript設計模式學習筆記"
date: 2015-12-04 14:29:29 +0800
categories: design partern
---javascript
函數運行在定義它的做用域中,而不是調用它的做用域中,利用這一點和閉包聯合使用,就能把變量保存在匿名函數中加以保護。java
// 檢查接口存在與否 // @param {string} name 接口名稱 // @param {Array} methods 接口方法 function Interface(name, methods) { if(arguments.length !== 2){ throw new Error('Interface constructor called with ' + arguments.length + 'arguments,but expected exactly 2.'); } this.name = name; this.methods = []; for (var i = 0; i < methods.length; i++) { if (typeof methods[i] !== 'string') { throw new Error('Interface constructor expects method names to be passed in as a string.'); } this.methods.push(methods[i]); } } // 檢查接口存在與否 // @param {[type]} object 實例對象 // @param {[type]} object 接口名稱 Interface.ensureImplements = function(object) { if(arguments.length < 2){ throw new Error('Function Interface.ensureImplements called with ' + arguments.length + 'arguments,but expected at least 2.'); } for (var i = 1; i < arguments.length; i++) { var interface = arguments[i]; if(interface.constructor !== Interface) { throw new Error('Function Interface.ensureImplements expects arguments'+ 'two and above to be instances of Interface.'); } for (var j = 0; j < interface.methods.length; j++) { var method = interface.methods[j]; if(!object[method] || typeof object[method] !== 'function') { throw new Error('Function Interface.ensureImplements: object' + 'does not inplement tht' + interface.name + 'interface.method' + method + ' was not found'); } } } };
function Book(isbn,title,author){} Book.prototype.method = function() {};
做用域,嵌套函數,閉包
返回一個內嵌函數,是建立閉包的經常使用手段編程
function Mixin() {}; Mixin.prototype = { method1:function(){}, method2:function(){}, .... } function Myclass(){}; augument(Myclass,Mixin,'method2'); //繼承Mixin的Method2方法 new Myclass().method2() // 調用Method2方法 // 繼承其餘類的方法 function augment(recivingClass, givingClass, methodName) { if(arguments[2]){ for (var i = 2; i < arguments.length; i++) { recivingClass.prototype[arguments[i]] = givingClass.prototype[arguments[i]]; }; }else { for(methodName in givingClass.prototype) { if(!recivingClass.prototype[methodName]) { recivingClass.prototype[methodName] = givingClass.prototype[methodName]; } } } }
var MyNameSpace = {}; MyNameSpace.Singleton = (function(){ // pravite members. var ... //私有變量必須用var 聲明 // public members. return { publicAttribute: xxx, publicMethod: function(){} } })();
var MyNameSpace = {}; MyNameSpace.Singleton = (function(){ var uniqueInstance; //代表單體是否已經被實例化過 function constructor(){ // pravite members. var praviteAttribute; //私有變量必須用var 聲明 // public members. return { publicAttribute: xxx, publicMethod: function(){} } } return { getInstance:function() { if(!uniqueInstance){ uniqueInstance = constructor(); } return uniqueInstance; } } })(); // 調用方法改成:MyNameSpace.Singleton.getInstance().publicMethod()
工廠模式的主要好處在於消除對象之間的耦合,經過使用工廠模式,能夠把全部實例化代碼集中在一個位置。設計模式
讓接口可橋接,抽象函數功能。瀏覽器
簡化類的接口,如經常使用的setCss函數,event處理函數,把瀏覽器差別封裝起來,提供便利的接口,提升編程效率。閉包
用於不一樣接口之間的轉換,銜接。函數
若是說實例對象在頁面不止一處被使用,能夠建立函數檢查實例的使用狀態,把未使用的對象拿來使用,避免建立多個重複實例。性能
// 虛擬代理 function DynamicProxy() { this.args = arguments; this.initialized = false; var that = this; // 觸發初始化 addEvent(parent, type, that._initialize); } DynamicProxy.prototype = { // 初始化(本體實例化) _initialize: function() { this.parent = new Parent(this.args); var that = this; this.interval = setInterval(function(){that._checkInitialization();},100); }, // 檢查初始化 _checkInitialization:function() { if (this.parent.parentMethod !== null) { clearInterval(this.interval); this.initialized = true; } }, // 若是初始化完成,調用本體方法 method: function(args) { if(!this.initialized) { return; } return this.parent.method(args); } };