原文出自于本人个人博客网站:https://www.dzyong.com(欢迎访问)
本文链接地址: https://www.dzyong.com/#/ViewArticle/85(转载请标注来源)
设计模式系列博客:JavaScript设计模式系列目录(持续更新中)
面对对象编程是一种程序设计范型。它将对象作为程序的基本单元,将程序和数据封装其中,以提高程序的重用性、灵活性和扩展性。
我们以一个例子来开始学习。需求:对用户输入的用户名、邮箱、密码等进行验证。
实现这个需求很简单,小白的写法是:
function checkName() {
//验证姓名
}
function checkEmail() {
//验证邮箱
}
function checkPassword() {
//验证密码
}
这是一种函数的形式来进行验证,但是这种写法的风险很大,如果是个人开发这样写的话问题不大,但是如果是团队开发,如果别人也定义了同样的方法就会覆盖掉原有的功能了。因为这3个函数属于全局变量。
用对象收编变量
为了避免这样的问题发生,我们可以使用对象收编变量。
var CheckObject = {
checkName : function(){
//验证姓名
},
checkEmail : function(){
//验证邮箱
},
checkPassword : function(){
//验证密码
},
}
此时将所有的函数作为CheckObject 对象的方法,这样我们就只有了一个对象,并且我们使用它也很简单,比如说检测姓名 CheckObject.checkName (),只是比原来的前面多了一个对象的名称。
对象的另一种形式
对象还有另一种形式,可以先声明对象,然后在为它添加方法,所以你可以这么做:
var CheckObject = function(){}
CheckObject .checkName = function() {
//验证姓名
}
CheckObject .checkEmail = function() {
//验证邮箱
}
CheckObject .checkPassword = function() {
//验证密码
}
真假对象
如果你想复制这个对象可以这样写:
var CheckObject = function(){
return {
checkName : function(){ //验证姓名 },
checkEmail : function(){ //验证邮箱},
checkPassword : function(){ //验证密码},
}
}
这样做的好处是,每当调用这个函数的时候,把之前的那个对象返回出来,当别人每次调用这个函数的时候都返回一个新的对象,这样每个人使用时就互不影响了。
var a = CheckObject ();
a.checkName ();
类也可以
虽然创建新对象完成了需求,但是它不是一个真正意义上类 的创建方式,并且创建的对象a和对象CheckObject 没有任何关系,接下来我们就来创建也真正的类:
var CheckObject = function(){
this.checkName = function(){ //验证姓名 }
this.checkEmail = function(){ //验证邮箱 }
this.checkPassword = function(){ //验证密码 }
}
类的创建方法就不能像对象那样,既然是一个类,就要用关键字new来创建
var a = new CheckObject ();
a.checkName ();
一个检测类
所有的方法放在函数内部了,通过this定义的,所以每一次通过new关键字创建新对象的时候,新创建的对象就会对类的this上的属性进行复制。所以这些新创建的对象都有自己的一套方法,但是这么多有时候造成的消耗是很奢侈的,我们需要处理一下:
var CheckObject = function(){}
CheckObject .prototype.checkName = function(){ //验证姓名 }
CheckObject .prototype.checkEmail = function(){ //验证邮箱 }
CheckObject .prototype.checkName = checkPassword (){ //验证密码 }
这样创建对象实例的时候,创建出来的对象所拥有的方法都是一个,因为他们都要依赖prototype原型一次寻找,而找到的方法都是同一个,他么都绑定在CheckObject对象类的原型上。当然我们还可以对上面的方式进行简化。
var CheckObject = function(){}
CheckObject .prototype = {
checkName : function() { //验证姓名 },
checkEmail : function() { //验证邮箱 },
checkName : function() { //验证密码 },
}
但是千万要注意,这两种方式不能混着用,否则一旦混用,如在后面为对象的原型对象赋值新对象时,它将覆盖掉之前对prototype对象赋值的方法。
使用还是如同之前一样的方法使用;
var a = new CheckObject ();
a.checkName ();
a.checkEmail ();
a.checkName ();
方法还可以这样用
在之前的基础上还可以进一步的优化,不知你发现没,调用3个方法我们需要写3遍a,这是可以避免的,在声明的每一个方法末尾返回当前对象(JavaScript中this指向当前对象)。
var CheckObject = {
checkName : function() { //验证姓名 return this; },
checkEmail : function() { //验证邮箱 return this; },
checkName : function() { //验证密码 return this; },
}
此时我们就可以这样用:
CheckObject .checkName().checkEmail().checkName()
是不是感觉简洁了很多,当然同样的方式也可以放到类的原型对象中:
var CheckObject = function(){}
CheckObject .prototype = {
checkName : function() { //验证姓名 return this; },
checkEmail : function() { //验证邮箱 return this; },
checkName : function() { //验证密码 return this; },
}
var a = new CheckObject();
a.checkName().checkEmail().checkName()
函数的祖先
prototype.js是一款JavaScript框架,里面为我们方便的封装了很多方法,最大的特点就是可以对源生对象(Function、Array、Object等)的扩展,比如你想给一个函数都添加一个邮箱检测的方法可以这么做:
Function.prototype.checkEmail = function(){
//验证邮箱
}
这样使用这个方法就方便了很多:
函数的形式
var a = function(){}
a.checkEmail ();
类的形式
var a = new Function();
a.checkEmail ();
但是为了安全我们不允许这么做,因为这会污染源生的对象Function,造成不必要的开销,你可以抽象出一个统一添加方法的功能:
Function.prototype.addMothed = function(name, fn) {
this[name] = fn
}
你就可以使用如下的方式来添加你的方法
var motheds = function() {} 或 var motheds = new Function()
motheds.addMothed('checkEmail ', function(){ // 检测邮箱 })
同样也可以链式添加
Function.prototype.addMothed = function(name, fn) {
this[name] = fn;
return this;
}
motheds.addMothed('checkEmail ', function(){ // 检测邮箱 })
.addMothed('checkName', function(){ // 检测姓名 })
也是返回方法的this来实现
motheds.addMothed('checkEmail ', function(){ // 检测邮箱 return this; })
使用类调用方式
Function.prototype.addMothed = function(name, fn) {
this.prototype.[name] = fn;
return this;
}
使用类的方式时要注意,不能直接使用,需要通过new关键字来创建对象。
var m = new Methods();
m.checkEmail ()
原文出自于本人个人博客网站:https://www.dzyong.com(欢迎访问)
转载请注明来源: 邓占勇的个人博客 - 《JavaScript设计模式——面对对象的编程》
本文链接地址: https://www.dzyong.com/#/ViewArticle/85