1.编程风格
/* Start and stop animations using function 面向过程的方法 */
funciton startAnimation(){
....
};
function stopAnimation()
{
...
};
/* Anim class */
var Anim = function() {
...
};
Anim.prototype.start = function() {
...
};
Anim.prototype.stop = function() {
...
};
//usage
var myAnim = new Anim();
myAnim.Start();
myAnim.stop();
/* Anim class, with a slightly different syntax for declaring methods 把类封装在一条声明中 */
var Anim = function (){
...
};
Anim.prototype = {
start:function(){
...
},
stop:function() {
...
}
}
/* function.prototype.method 用于为类添加新方法,可被链式调用 */
Function.prototype.method = function(name, fn){
this.prototype[name] = fn;
return this; //添加可被链式调用
};
//prototype.method方法使用:
Anim.method('start', function() {
...
});
Anim.method('stop', function() {
...
});
//链式调用
Anim.method('start', function() {
...
//function() { ... } 这样的语法创建匿名函数,可以被赋值变量
}).method('stop', function() {
...
});
/* 匿名函数 function() { ... } */
(function () {
var foo = 10;
var bar = 2;
alert(foo*bar);
})();
//这个函数在定义乌之后便立即执得,不用赋值给一个变量,最后的括号立即对它调用
(function(foo, bar) {
//带参数的写法
alert(foo*bar);
})(10,2);
//jquery说明:
写法一:
$(document).ready(function() {
…
});
写法二:
jQuery(function($) {
…
});
写法三:
$(function() {
…
});
2.闭包(closure):是一个受到保护的变量空间,由内嵌函数生成。javascript具有函数级的作用域:在函数内部的变量在函数外部不能被访问。
//一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中.
/*私用变量(private)*/
var baz;
(function() {
var foo = 10;//私有变量
var bar =2; //私有变量
bar = funciton() {
return foo * bar;
};
})();
baz();
/*闭包实现私用成员(只能在对象内部访问的变量)*/
//特权方法(privileged):需要访问这些变量和函数的方法。它是公用方法,能够访问私用属性,this.[function名]
var Book = function(newIsbn, newTitle, newAuthor) { //impliments publication
//private attributes.
var isbn, title, author;
//private Method
function checkIsbn(isbn) {
...
}
//privileged Methods.(getIsbn,setIsbn,getTitle,setTitle,getAuthor,setAuthor)
this.getIsbn = function() {
return isbn;
};
this.setIsbn = function(newIsbn) {
...
}
//Constructor code
this.setIsbn(newIsbn);
this.setTitle(newTitle);
this.setAuthor(newAuthor);
};
//Public, non-privileged Methods.
//任何不需要直接访问私用属性的方法都可以Book.prototype中声明。
//需要直接访问私用成员的方法才应该被设计为特权方法。特权方法太多又会占用内存,因为每个对象实例都包含了所有特权方法的新副本。
Book.prototype = {
display:function() {
...
}
};
3.接口实现(interface)
/*interface类的定义*/
//Constructor
var Interface = function(name, methods) {
if(argument.length != 2) {
throw new Error("实现接口必须要满足2个以上的参数");
}
this.name = name;
this.methods = [];
for(var i = 0, len = methods.length, i< len; i++) {
if(typeof methods[i] !== 'string') {
throw new Error("实现的方法名必须是字符");
}
this.methods.push(methods[i]);
}
};
//Static class method.
Interface.ensureImplements = function(object) {
if(arguments.length < 2) {
throw new Error("需要2个以上参数");
}
for(var i =1, len = arguments.length; i < len; i++) {
//interface为接口,一定要实现Interface类
var interface = arguments[i];
if(interface.Constructor !== Interface) {
throw new Error("two and above to be instances of Interface");
}
for (var j=0, methodsLen = interface.methods.length; j < methodsLen; j++) {
var method = interface.methods[j];
if (!object[method] || typeof object[method] !== 'function') {
throw new Error("Function Interface.ensureImplements: object " +
"does not implements the " +
inter_face.name +
"interface.Method " +
method +
"was not found.");
}
}
}
}
//调用方法,检测接口实现:
//定义接口Composite,实现add,remove,getChild三种方法
var Composite = new Interface('Composite',['add','remove','getChild']);
//定义接口FormItem,实现save方法
var FormItem = new Interface('FormItem',['save']);
//判断对象是否实现了上述两个接口
var object = new Class();
Interface.ensureImplements(object,Composite,FormItem);
4.链式调用(出处:http://snandy.iteye.com/blog/748348)
//方法链一般适合对一个对象进行连续操作(集中在一句代码)。一定程度上可以减少代码量,缺点是它占用了函数的返回值。
/*方法体内返回对象实例自身(this)*/
//定义了function/类ClassA。有三个属性/字段prop1,prop2,prop3,三个方法methed1,method2,method3分别设置prop1,prop2,prop3。
function ClassA(){
this.prop1 = null;
this.prop2 = null;
this.prop3 = null;
}
ClassA.prototype = {
method1 : function(p1){
this.prop1 = p1;
return this;
},
method2 : function(p2){
this.prop2 = p2;
return this;
},
method3 : function(p3){
this.prop3 = p3;
return this;
}
}
//调用
var obj = new ClassA();
obj.method1(1).method2(2).method(3); // obj -> prop1=1,prop2=2,prop3=3
/*对象传入后每次调用返回函数自身*/
//注意ClassB的method1,method2,method3中不再返回this了。
/**
* chain 精简版
* @param {Object} obj
*/
function chain(obj){
return function(){
var Self = arguments.callee; Self.obj = obj;
if(arguments.length==0){
return Self.obj;
}
Self.obj[arguments[0]].apply(Self.obj,[].slice.call(arguments,1));
return Self;
}
}
//定义的function/类ClassB
function ClassB(){
this.prop1 = null;
this.prop2 = null;
this.prop3 = null;
}
ClassB.prototype = {
method1 : function(p1){
this.prop1 = p1;
},
method2 : function(p2){
this.prop2 = p2;
},
method3 : function(p3){
this.prop3 = p3;
}
}
//调用方法1
var obj = new ClassB();
chain(obj)('method1',4)('method2',5)('method3',6); // obj -> prop1=4,prop2=5,prop3=6
//调用方法2
// result -> prop1=4,prop2=5,prop3=6
var result = chain(obj)('method1',4)('method2',5)('method3',6)();
chain(obj)('method1',4)('method2',5)('method3',6); // obj -> prop1=4,prop2=5,prop3=6
5.单例/单体模式(Singleton)
/*对象直接量实现最基本,最简单的单体*/
var Singleton = {
attr1 : 1,
attr2 : 'hello',
method1 : function(){alert(this.attr2);},
method2 : function(arg){}
}
Singleton.method1();
/*闭包实现私有成员的单体*/
var Singleton = function(){
var attr = 1, fn = function(){};
return {
method : function(){ fn(); },
getAttr : function(){ return attr; }
};
}();
Singleton.method();
Singleton.getAttr();
/*闭包实现私有成员的惰性实例化单体*/
var LazySingleton = function(){
var attr = 1, fn = function(){};
var obj = {
method : function(){ fn(); },
getAttr : function(){ return attr; }
};
function init(){
return obj;
}
return {getInstace: init};
}();
LazySingleton.getInstance().method();
LazySingleton.getInstance().getAttr();