JavaScript code的编写模式多种多样,那么接下来总结一下大概都有哪几种,看看你是否都使用到了这些模式和思维:
-
Separation of concerns
即是我们平时挂在嘴边的行为、样式、结构分离(Content-markup、Presentation-CSS、Behavior-JavaScript),这在代码的扩展性、可维护性、易迁移性方面都可以得到很大的提升 -
Literals,JSON,namespace
Literals指的是codding尽量字面量化,对象字面量、数组字面量、函数字面量、正则字面量等等,这些都比使用new来实例Object、Array、Function性能上更好,甚至也推荐使用变脸的形式来声明函数,避免直接使用function来声明一个函数。
JSON提供一种更简洁、更直观的数据传输,在大小和解析方面都胜于XML。
namespace是尽量将每一个APP封装在一个独立的命名空间下,避免跟其他的APP模块产生耦合,产生错误。“低耦合”是namespace的一个终极目标。 -
Self-executing functions
顾名思义,就是指自定义函数,它用的比较多的场合是在闭包中,提供给code一个纯净的上下文执行环境,而不会造成全局变量泛滥 -
Callbacks
回调函数,用过“鸡查询(jQuery)”的人都知道,在执行完一个函数之后,再调用回调函数进行下一步的操作,做到了“流畅的执行流”。 -
Borrowing methods
别看Borrowing这个单词是“借”的意思,感觉有点高深,其实就是利用了apply和call两个方法来借用其他类或者对象的方法来实现功能,比较多的场合是借用数组的一些方法,比如slice、join等等,比如:[].apply(arguments,[1,3])。这只是普通用的比较多的情况,但是它还可以用在这样的一个场合,类似于“继承”:我首先使用一个“基类”—即是一个包含通用的方法和属性的对象,之后其他的结构跟它类似的对象就可以通过apply或者call来“借用”这个“基类”的方法,说的可能有些枯燥,上点代码:
[javascript]
var Base={
name:"",
"getName":function(){
return this.name;
},
"setName":function(name){
this.name=name;
}
}
//有了上面这个“骨架”之后,接下来就可以“借用”了
//比如从服务器端获得了这样的一个JSON结构:
var json={
"test1":{ "name":"lilei","age":22},
"test2":{ "name":"Sam","age":30},
"test3":{ "name":"Susa","age":15}
}
//这样我们就可以这样来调用了:
alert(Base.getName.call(json.test1));
///////////////
////////这只是个简单的例子,实用性并不高,提供的是一种设计思路,在某种场合或许就可以利用它
[/javascript] -
Functions returning functions
在函数中再返回函数,这也是比较普通的了,为特定的场合所使用 -
Functions overwriting themselves
函数重写它自己,这点或许很多人都知道怎么回事,但是怎么去利用它,还比较模糊。它的一个非常适用的场合就是处理浏览器兼容性的判断,也就是所谓的“Lazy Definition”。它就是在第一次执行的时候就根据不同的条件进行判断,来重写自身函数,这样在第二次之后的调用中就可以直接调用,而无需再判断兼容性等等,比如:
[javascript]
var addEvent=function(el,type,fn){
addEvent=el.addEventListener ? function(el,type,fn){
el.addEventListener(type,fn,false);
}:function(el,type,fn){
el.attachEvent("on"+type,fn);
};
return addEvent(el,type,fn);
}
[/javascript] -
Function properties
这个就是给函数添加属性,通常使用这个无非是为了临时储存数据或者在这个函数的命名空间下在执行期间一直储存数据。比如cache的实现等。其实这里的Function可以延伸到DOM节点等任何可以设置属性的对象上。不知道大家有没有看过John Resig写的那两个addEvent和removeEvent方法,就是在DOM中临时储存数据来实现在IE下正确的removeEvent。 -
Configuration object
看过或者使用过YUI的,都知道它其中的对象、类、方法中都充斥着config参数,这里说的Configuration object多多少少就是这种应用,不过一种比较好的说法是“在参数列表中,如果参数数目多,那么将必须的参数独立起来,其他的可选参数都放到一个字面量对象里,即是Config参数”,这是有一定合理性的,一来代码看起来比较直观,明确区分了必须的参数和可选的参数,同时使得可选的参数无需按照顺序罗列出来。 -
Constructor return values
在构造函数中返回值。这里就有一点误区了:如果返回的值是对象,那么new实例化的时候,实例对象就是该返回的对象,如果是普通的数值(字符串、数字、布尔值等),就忽略该返回的值,按照正常的方式实例化。 -
Forgeting new
把new给“忘记”了吧。这里的“忘记”并不是说不去使用new,或者忽略它的存在,它在很多场合下还是得用(比如继承、一些带变量的正则对象等),这里的Forgeting的意思也是从继承等的角度去说的,尽量避免去使用new来实例化对象,道格拉斯曾经提出一种“伪函数化”的继承方式,例如:
[javascript]
var Base = function(name){
var that = {};
that.name=name;
return that;
}
var subClass=function(name,age){
var that = Base(name);
that.age=age;
return that;
}
//例如上面的例子,“继承”的方式就是利用了一个字面量作为载体,进行添加、删除、修改属性和方法等等,这样就可以给不同的子类扩展不同的方法和属性。
[/javascript] -
Chaining
链式调用,“鸡查询”库可谓是开创了先河,它的简易性和便利性使得它的用户群猛彪,使得Prototype、ExtJs、YUI等不得不也借鉴它的方法调用的方式。 -
Inheritance
继承。对,这里说的就是继承,面向对象思想中的其中之一,其实在一般的程序中,很少用到继承的方式来实现功能,但是如果从代码的扩展性、维护性等方面考究,以及从库、框架的角度来架构的时候,可能就需要继承这个技巧来实现整个代码的编写了。 -
Mixins
这个词不好理解,YUI中的augment函数或许有些人看过它的源码,基本的应用场合是扩展对象,例如:
[javascript]
/* Augment function, improved. */
function augment(receivingClass, givingClass) {
if(arguments[2]) { // Only give certain methods.
for(var i = 2, len = arguments.length; i < len; i++) {
receivingClass.prototype[arguments[i]] = givingClass.prototype[arguments[i]];
}
}
else { // Give all methods.
for(methodName in givingClass.prototype) {
if(!receivingClass.prototype[methodName]) {
receivingClass.prototype[methodName] = givingClass.prototype[methodName];
}
}
}
}
[/javascript]
之前我也写过一片博文《享元类ShareClass》,原理跟这个差不多。 -
Private variables
私有变量。“保持全局环境变量的干净”,这个被说的很多了。JavaScript可以模拟出私有成员、特权函数(即是静态方法),而实现这个仅仅需要一个闭包函数作为上下文执行环境,来于闭包外部的执行环境区分开来。静态方法仅仅需要给该对象或者构造函数添加方法,这样就使得该方法具有独享性。 -
Dynamic script tags
动态添加script标签。这个主要是用于异步动态加载外部的js文件,使得js的加载和执行不会阻塞后续资源的加载。这里罗列了七种加载js的方式:http://www.ilovejs.net/lab/loadjs/。不过有一点值得说明的是:浏览器解析过的script标签,浏览器不会重新去解析,即使你通过text属性修改了script标签内的代码,或者修改了script标签的src属性,浏览器也不会去重新解析它。 -
Modules
模块,也叫做组件。模块化开发已经广泛为前端界的人所知晓了,它并不是一个很新的东西,而是一种代码设计的思维,从代码的可维护性、独立性、松散耦合方面来设计代码。这个就跟面向对象的思想一样,都是一种设计方式,来适用于不同的场合。
沙发!
好久没来这儿,来了之后感觉好多人。