本文将用一个例子来演示:启动和停止一个动画,用以说明面向对象的概念:
传统编程:
//定义函数/方法,然后调用
function startAnimation(){
...
}
function stopAnimation(){
...
}
startAnimation()
stopAnimation()
这么做很简单,但你无法创建可以保存状态并且具有一些仅对其内部状态进行操作的方法的动画对象。
接下来我们再看另一种形式:创建一个类,然后再new一个类进行调用(它的原型方法):
//创建一个 class 类
var Anim = function(){
...
}
Anim.prototype.start = function(){
...
}
Anim.prototype.stop = function(){
...
}
//调用
var myAnim = new Anim();
myAnim.start()
myAnim.stop()
这种方法更近了一步,但它主要运用的是(原型)的方法,即 prototype 属性。
根据习惯它还有另一种写法:即把类的定义封装在一条声明中:
//将类的定义封装在一条声明中:
var Anim = function(){
...
}
Anim.prototype = function(){
start:function(){
...
},
stop:function(){
...
},
}
...(调用同上,省略)
这在传统的面向对象程序员看来,可能更眼熟一点,他们习惯于看到类的方法声明内嵌在类的声明中。
我们再看一个跟继承有关的写法:
//先创建一个'公有' 类
Function.prototype.method = function(name,fn){
this.prototype[name] = fn
}
//创建 Anim 类,再为这个类添加新的方法:
var Anim = function(){
...
}
Anim.method('start', function(){
....
})
Anim.method('stop', function(){
....
})
//调用(略)
Function.protptype.method 用于为类添加新的方法。它有两个参数:
1. 第一个是字符串,用于说明新方法的名称;
2. 第二个是用作新方法的函数。
同时,我们还可以进一步修改 Function.protptype.method ,使其可以被链式调用(这样我们只需要让它返回 this 值即可):
//链式调用
Function.protptype.method = function( name , fn ){
this.prototype[name] = fn;
return this; //划重点!
}
//看下调用
var Anim = function(){
...
}
Anim.
method('start',function(){
....
}).
method('stop',function(){
....
});
本文通过一个小案例演示了用 javascript 完成同一项任务的5种不同的编程风格,你可能觉得其中的某种方法比别的方法更为合意,其实,这是件好事,它充分体现了 javascript 编程的灵活性。它允许你用你最适合的风格进行工作。那么,你偏好的是那种呢?
本文内容来源于《JavaScript设计模式》(【美】Ross Harmes Dustin Diaz 著 谢廷晟 译),编写本文的初衷是帮助笔者自己总结学习而用,当然,笔者本人也乐于分享自己的学习总结,欢迎评论,指教。