用一个变量来标志当前是否已经为某个类创建过对象,如果是,则在下一次获取该类的实例时,直接返回之前创建的对象。
实现单例模式
//1.实现单例模式
var Singleton = function (name) {
this.name = name;
};
Singleton.prototype.getName = function() {
alert(this.name);
};
Singleton.getInstance = (function() {
var instance = null;
return function(name) {
if (!instance) {
instance
继续阅读 »
模版方法是一种只需要使用继承就可以实现的非常简单的模式。他由两部分组成,第一部分是抽象父类,第二部分是具体实现子类。通常在抽象父类中封装了子类的算法框架,包括实现一些共用方法以及封装子类所有方法的执行顺序。子类通过继承这个抽象类,也继承了整个算法结构,并且可以选择重写父类的方法。
Coffee or Tea
假设我们现在要泡一杯咖啡步骤如下:
* 把水煮沸
* 用沸水冲泡咖啡
* 把咖啡倒进杯子
* 加糖和牛奶
泡茶的步骤:
* 把水煮沸
* 用沸水浸泡茶叶
* 把茶水倒进杯子
* 加柠檬
经过比较,我们可以发现泡茶和泡咖啡有以下共同点:
原料不同。一个是茶一个是咖啡,但是我们都可以把它们抽
继续阅读 »
高阶函数是至少满足下列条件之一的函数
* 函数可以作为参数被传递
* 函数可以作为返回值输出
(js这么好的语言中的函数当然满足 ^^)_
函数作为参数传递
把函数当作参数传递,可以抽离出一部分容易变化的业务逻辑,把这部分业务逻辑放在函数中,可以分离业务代码中变与不变的部分。
回调函数,ajax异步,callback
var getUserInfo() = function(userId, callback) {
$.ajax('http://xxx.com/getUserInfo?' + userId, function(data) {
if (typeof(callback === '
继续阅读 »
闭包是js中一个难懂又必须征服的概念,他的形成与变量作用域以及变量的生存周期密切相关。
变量作用域和生存周期
作用域,按字面理解,就是指变量的有效范围,超出这个范围就无法访问。
在函数中,里面函数可以访问外面的变量,但是外面无法访问内部变量。举个简单例子:
var a = 1;
var fun1 = function() {
var b = 2;
var fun2 = function() {
var c = 3;
alert(b); //2
alert(c); //3
}
fun2();
alert(c); //c is not de
继续阅读 »
虚拟代理实现图片预加载
图片预加载:图片过大或者网络不佳时,图片位置有段时间会是一片空白,常见的用一张loading占位,然后异步加载图片,等图片加载好了再把它填充到img节点里。
var myImage = (function() {
var imgNode = document.createElement('img');
document.body.appendChild( imgNode );
return {
setSrc : function( src ) {
imgNode.src = src;
}
}
})();
var pr
继续阅读 »
迭代器模式是指提供一种方法,顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。迭代器模式可以把迭代的过程从业务逻辑中分离出来,在使用迭代器模式之后,即使不关心内部构造,也可以按顺序访问其中的每个元素。
jQuery中的迭代器
迭代器模式无非就是循环访问聚合对象中的各个元素。比如jQuery中的$.each函数,其中回调函数中的i为当前 索引,n为当前元素,代码如下
$.each([1, 2, 3], function(i, n) {
console.log('当前坐标:' + i);
console.log('当前值:' + n);
});
然而,作为一个合格的前端开发者,我们不应该只是会用,而
继续阅读 »
组合模式
组合模式将对象组合成树形结构,以表示“部分-整体”的层次结构。除了用来表示树形结构之外,组合模式的另一个好处是通过对象的多态性表现,使得用户对单个对象和组合对象的使用具有一致性。
请求在树中传递的过程
在组合模式中,请求在树中传递的过程总是遵循一种逻辑。
请求从树的最顶端的对象往下传递,如果当前处理请求的对象是叶对象,叶对象自身会对请求做相互相应的处理;如果当前处理请求对象是组合对象,组合对象则会遍历它下面的节点,将请求继续传递。
总之,组合对象的请求是从上到下沿着树传递,直到树的尽头。作为客户,只要关心树最顶层的组合对象,客户只需要请求这个组合对象,请求便会向下延续。
现在,假设一个需求,我们需要一个超级
继续阅读 »
装饰者模式:给对象动态地增加职责。跟继承相比,装饰者是一种更轻便灵活的做法,是一种“即用即付”的方式。
js的装饰者
假设我们在编写一个飞机大战游戏,这个飞机可以升级,发射导弹,发射原子弹
var plane = {
fire: function() {
console.log('发射普通子弹');
}
};
var missileDecorator = function() {
console.log('发射导弹');
};
var atomDecorator = function() {
console.log('发射原子弹');
};
var fire1 = plane.f
继续阅读 »
一些重构的建议:
提炼函数
* 避免出现超大函数
* 独立出来的函数有助于代码复用
* 独立出来的函数更容易被覆写
* 独立出来的函数如果拥有一个良好的命名,
* 它本身就起到了注释的作用。
比如在一个负责取得用户信息的函数里面,我们还需要打印跟用户信息有关的log,那么打印log的语句就可以被封装在一个独立的函数里:
var getUserInfo = function() {
ajax('http://xxx.com/userInfo', function(data) {
console.log('userId: ' + data.userId);
console.log('u
继续阅读 »
单一职责原则
就一个类而言,应该仅有一个引起它变化的原因。在JavaScript中,需要用到类的场景并不太多,单一职责原则(SRP)更多的是被运用在对象或者方法级别上。
总之,SRP原则体现为:一个对象(方法)只做一件事情。
例如:
代理模式
迭代器模式
单例模式
装饰者模式
但是,并不是所有的职责都应该一一分离的,一方面如果随着需求的变化,有两个职责是同时变化的,那就不必分离他们。比如在ajax请求的时候,创建xhr对象和发送xhr请求几乎总是在一起的,那么创建xhr对象的职责和发送xhr对象的职责就没有必要分开。
另一方面,职责的变化轴线仅当它们确定会发生变化时才有意义,即使两个职责已经被耦合在一起但他们
继续阅读 »