JavaScript设计模式学习心得一

小小的需求

有这么一个需求,完成一个表单验证的功能,仅需验证用户名、邮箱、密码。

看到这里微微一笑,写出如下代码:

function checkName(){
  //验证姓名
}
function checkEmail(){
  //验证邮箱
}
function checkPassword(){
  //验证密码
}

完事!经验丰富一点的同学表示,你这也行?满屏的全局变量,如果多人协作,你这个很容易相互覆盖的,那么可以将他们放在一个变量中保存,这样就大大降低了覆盖或被覆盖的风险,当然一旦被覆盖,所有功能都会失效,也容易发觉。

var CheckObject = {
  checkName : function(){
     //验证姓名
  },
  checkEmail : function(){
     //验证邮箱
  },
  checkPassword : function(){
     //验证密码
  }
}

这样我们将所有的函数作为CheckObject对象的方法,这样我们就只有一个对象,使用也很简单,比如检测姓名CheckObject.checkName()。当然我们既然可以通过点语法来使用方法,我们是不是也可以这样创建呢?

var CheckObject = function(){}
CheckObject.checkName = function(){
  //验证姓名
}
CheckObject.checkEmail = function(){
  //验证邮箱
}
CheckObject.checkPassword = function(){
  //验证密码
}

        这种方法的使用和前面的方式一样,比如CheckObject.checkName()。

真假对象

经验更丰富的同学就会说了,哎呀,你这个的确是能满足你的需求,但是当别人想用你写的对象方法时就有些麻烦了,因为这个对象不能复制一份,或者说这个对象类在用new关键字创建新的对象时,新创建的对象时不能继承这些方法的。

有的同学又要问了,那我复制了又有什么用呢?那么我们举个栗子,假如你喜欢设计模式,你买了这本书,然后回去你的小伙伴看见了,感觉很有用,他们也想要怎么办?书就一本。但如果你买的是一台打印机,那么好吧,即使你的小伙伴再多,你也有能力给他们每人打印一本。那么问题来了,我们要怎么做?

var CheckObject = function(){
  return {
     checkName : function(){
       //验证姓名
     },
     checkEmail : function(){
       //验证邮箱
     },
     checkPassword : function(){
       //验证密码
     }
  }
}

这样每当调用这个函数的时候,把我们之前写的那个对象返回出来,当别人每次调用这个函数时都返回了一个新对象,这样执行过程中明面上时CheckObject对象,可实际上是返回的新对象。这样每个人在使用时就互不影响了。比如:

var a = CheckObject();
a.checkName();

那么经验老道的同学说,你这个虽然通过创建了新对象完成了我们的需求,但是它不是一个真正意义上的类的创建方式,并且创建的对象a和对象CheckObject没有任何关系(返回出来的对象本身就与CheckObject对象无关),所以我们还要稍加改造一下。

var CheckObject = function(){
  this.checkName = function(){
     //验证姓名
  }
  this.checkEmail = function(){
     //验证邮箱
  }
  this.checkPassword = function(){
     //验证密码
  }
}

像这样的对象就可以看成类了,所以我们需要用new关键字来创建了。

var a = new CheckObject();
a.checkEmail();

这样如果我和我得小伙伴都对类实例化了(用类创建对象),那么我们每个人都会有一套属于自己的方法。因为我们把所有方法放在了函数内部,通过this定义,所以每一次通过new关键字创建新对象的时候,新创建的对象都会对类的this上的属性进行复制。然而有时候这么做造成的消耗是很奢侈的,我们需要进一步处理一下。

var CheckObject = function(){};
CheckObject.prototype.checkName = function(){
  //验证姓名
}
CheckObject.prototype.checkEmail = function(){
  //验证邮箱
}
CheckObject.prototype.checkPassword = function(){
  //验证密码
}

这样创建对象实例的时候,创建出来的对象所拥有额方法就都是一个了,因为他们都要依赖prototype原型依次寻找,而找到的方法都是同一个,它们都绑定在CheckObject对象类的原型上。这种方式我们要将prototype写很多遍,所以也可以这么写。

var CheckObject = function(){}
CheckObject.prototype = {
  checkName : function(){
     //验证姓名
  },
  checkEmail : function(){
     //验证邮箱
  },
  checkPassword : function(){
     //验证密码
  }
}

但是有一点,这两种方式不能混着用,一旦混用,如在后面为对象的原型对象赋值新对象时,那么它会覆盖掉之前对prototype对象的赋值的方法。这样使用方法如下:

var a = new CheckObject();
a.checkName();
a.checkEmail();
a.checkPassword;

大牛同学发话了,调用的是不错,但是你对对象a书写了3遍,这是可以避免的。在你声明的每个方法末尾处将当前对象返回,在JavaScript中this指向的就是当前对象,所以你可以将它返回。

var CheckObject = function(){}
CheckObject.prototype = {
  checkName : function(){
     //验证姓名
     return this;
  },
  checkEmail : function(){
     //验证邮箱
     return this;
  },
  checkPassword : function(){
     //验证密码
     return this;
  }
}

调用方法如下:

var a = new CheckObject();
a.checkName().checkEmail.checkPassword();

当然灵活的JavaScript有着更有意思的方法,下面这些是题外话。

//给原生对象Function添加一个方法
Function.prototype.addMethod = function(name,fn){
  this.prototype[name] = fn;
  return this;
}
//为methods添加方法
var Methods = function(){}
Methods.addMethod('checkName',function(){
  //验证姓名
  return this;
}).addMethod('checkEmail',function(){
  //验证邮箱
  return this;
})
//调用
var m = new Methods();
m.checkName().checkEmail();

这种直接污染了原生对象Function,所以别人创建的函数也会被你创建的函数所污染,造成不必要的开销,但你可以抽象出一个统一添加方法的功能方法。


  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值