prototype与面向对象取舍
使用prototype原型继承和使用面向对象,都可以实现闭包的效果。那么这两个的选择点,就是方法会不会产生多个实例。
例如,我们需要做一个闭包数组,并给他提供一个添加方法。
这两种写法都可以实现闭包,但是面向对象的写法,只能存在一个。我们无法对他进行初始化,而原型继承写法,我们则可以对他进行初始化操作。
所以,当我们这个方法,在整个程序中,是唯一的存在。我们可以使用面向对象的写法,如果可以存在多个,则使用prototype这种写法。
!(function () { //原型继承写法 var Validator = function(){ this.cache = []; }; Validator.prototype.add = function(item){ this.cache.push(item); }; var validator = new Validator(),validatorr = new Validator(); validator.add("test1"); console.log(validator.cache); validatorr.add("test2"); console.log(validatorr.cache); //面向对象写法 var Validator2 = { cache : [], add : function(item){ this.cache.push(item); } }; Validator2.add("test3"); console.log(Validator2.cache); Validator2.add("test4"); console.log(Validator2.cache); })()
调用父类构造函数
继承关系的两个对象,在实例的过程中,可以通过修改指向,来调整调用构造函数
!(function () { var A = function (light) { this.light1 = light; }; var B = function (light) { this.light = light; A.apply(this,arguments);//你需要手动调用A的构造方法 }; //给B赋值的同时,给A赋值 B.prototype = new A(); var C = new B(123); console.log(C.light); console.log(C.light1); })()
单例模式
保证一个类仅有一个实例,并提供一个访问它的全局访问点。例如:线程池,全局缓存,登录浮窗。
首先我们需要把单例的逻辑代码单独提取,然后使用惰性单例的方式,也就是返回方法。只有在点击的时候,才会进行执行。
javascript的单例,跟类不一样。无需创建多余的构造函数这些,直接创建全局变量即可。
!(function () { //管理单例的逻辑代码,如果没有数据则创建,有数据则返回 var getSingle = function(fn){ //参数为创建对象的方法 var result; return function(){ //判断是Null或赋值 return result || (result = fn.apply(this,arguments)); }; }; //创建登录窗口方法 var createLoginLayer = function(){ var div = document.createElement('div'); div.innerHTML = '我是登录浮窗'; div.style.display = 'none'; document.body.appendChild(div); return div; }; //单例方法 var createSingleLoginLayer = getSingle(createLoginLayer); //使用惰性单例,进行创建 document.getElementById('loginBtn').onclick = function(){ var loginLayer = createSingleLoginLayer(); loginLayer.style.display = 'block'; }; })() 单例模式
策略模式
定义一系列的算法,把它们一个一个封装起来。将算法的使用与算法的实现分离开来。
javascript的策略模式很简单,把算法直接定义成函数即可。
策略模式的优点与缺点
- 有效的避免许多重复的复制粘贴作业。
- 开闭原则的完美支持,算法完全独立易于切换、理解、拓展。
- 算法复用性强
- 使用组合和委托让Validator类拥有执行算法的能力,也是继承的一种轻便替代方式
缺点
- 会增加许多策略类或策略对象。
- 违反迪米特法则,会将strategy暴露给客户所有实现。
!(function () { //定义算法方法 var strategies = { "S":function(salary){ return salary * 4; }, "A":function(salary){ return salary * 3; }, "B":function(salary){ return salary * 2; } }; //执行算法 var calculateBouns = function(level,salary){ return strategies[level](salary); }; console.log(calculateBouns('S',2000)); })()
undefined终止循环
(写具体代码之前,先记录一个知识点)。当循环表达式为undefined时,循环会终止
!(function(){ var cale = [1,2,3]; for(var i= 0,validate;validate=cale[i];) { cale.shift(); console.log(validate); } })() //1,2,3
观察者模式
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。
例如事件绑定,就是一个标准的观察者模式
document.body.addEventListener('click',function(){ console.log(2); },false); document.body.click();
命令模式
命令模式指的是一个执行某些特定事情的指令。常见的应用场景是:有时候需要向对象发送请求,但不知道接受者是谁,也不知道请求的操作是什么。
例如:订餐,客人需要给厨师发送请求,至于那个厨师做,做的步骤。客人不知道。这就是命令模式。
//定义命令模式执行 var setCommand = function (button, func) { button.onclick = function () { func.execute(); }; }; var MenuBar = { refresh: function () { console.log("刷新页面"); } }; var RefreshMenuBarCommand = function (receiver) { return { execute: function () { receiver.refresh(); } } }; var refreshMenuBarCommand = RefreshMenuBarCommand("MenuBar"); setCommand(button1,refreshMenuBarCommand);
·························有待补充