当前位置: 首页 > Web前端 > HTML

JavaScript设计模式①正确使用面向对象编程的姿势

时间:2023-04-02 21:55:50 HTML

javascript是一门弱语言,其非凡的灵活性使其迅速成为几乎人人都会的语言,但是,你使用的姿势真的对吗?老大在之前的开发过程中:添加验证用户邮箱,验证用户短信……功能!functioncheckMessage(){...}functioncheckEmail(){...}function...//大量的函数这样写之后,function是一个全局变量,所以如果是全局的,就会不可避免地会影响到项目的javascript环境污染,可能会影响到其他同事。我们必须首先考虑它是否会影响其他人。如果同名的人覆盖了你的checkMessage,那么这样的BUG就很难找到了。为了不造成太大的全局污染,我们可以这样写:这样不会造成污染嘛,checkObject还是全局变量,有什么好处呢?想想如果Jquery的$被覆盖了,那么$.each|$.扩展|$(#id)|我们页面的$...就会失效,那么我们就很容易定位到问题所在:Jquery有问题!checkObject也是如此。当checkObject出现问题时,我们很容易定位错误。调用:checkObject.checkMessage()那么问题又来了:万一同事用我的checkObject做了什么怎么办?它可以直接使用我的方法吗?当然,问题是,你买了一本书,你要别人在上面乱涂乱画吗?我们可以这样修改:varcheckObject=function(){return{checkMessage:function(){},checkEmail:function(){},...}}我们通过函数调用返回方法,这样其他人就可以使用了像这样:varcheck=checkObject();检查.checkEmail();我们可以再改进一点,把checkObject看成一个java类,把checkMessage、checkEmail看成javapublicpublic方法,既然看成是类,我们可以把checkObject写成大写CheckObjectvarCheckObject=function(){this.checkMessage=function(){},this.checkEmail=function(){},...}被其他人调用:varcheck=newCheckObject();//既然是类,需要New来实例化check.checkEmail();每次通过new创建一个新的对象,新创建的对象都会复制类this上的属性,如果定义两个,那么复制两次,然后更多?是不是感觉有点奢侈?考虑一下我们可以使用javascript原型来创建它:varCheckObject=function(){}CheckObject.prototype.checkMessage=function(){},CheckObject.prototype.checkEmail=function(){},...你找到了吗麻烦?varCheckObject=function(){}CheckObject.prototype{checkMessage:function(){},检查电子邮件:function(){},...}这样我们所有的方法都被复制到CheckObject的原型上并连接起来,创建的对象依次通过原型查找,都绑定到CheckObject的原型上__proto__看看Jquery的原型链是不是很熟悉的方法?战友们,是不是很好奇Jquery的方法是怎么链式的呢?很简单,让我模拟一下varCheckObject=function(){}CheckObject.prototype={checkMessage:function(){...returnthis},checkEmail:function(){...returnthis},...varcheck=新检查对象();检查.checkMessage().checkEmail();就这么简单,我们只需要返回当前this引用的所有对象即可咳咳,言归正传,回到面向对象编程的话题。在java中,有private声明的私有变量,通过publicgettersetter方法通信,有static修饰的静态变量,静态方法,还有构造函数,那么javascript能不能用这个设计模式?好,跟我来:我们去商店买烟吧varSmoke=function(id,name){//privatepropertyvarnum=0;//对象的公共属性(需要new)this.id=id;//私有方法functioncheckID(){returntrue};//publicsettergetterconstructorthis.setName=function(name){this.name=name;}this.getName=function(){返回this.name;}//对象的公共属性(需要new)this.information=function(){//checkID()只能在Smoke内部调用if(checkID())returnthis.name+'cigarette'+'ordernumber:'+this.id}}Smoke.prototype={money:'10元',//公有属性(不用new)直接Smoke.money[有没有想过Array的长度?]other:function(){}}varsmoke=newSmoke(994857,'旋和门');烟雾信息();//"undefinedcigaretteordernumber:994857"ps:因为我们没有给Smoke的name属性赋值smoke.setName('轩禾门');//我们给smoke赋值.information();//"轩和门香烟订单号:994857"smoke.num;//undefinedps:明明是私有属性smoke.checkID();//errorisnotfunctionps:明显是私有方法如果我们没有newvarsmoke=Smoke(994857,'轩辕门');烟雾信息();//UncaughtTypeError:Cannotreadproperty'information'ofundefinedNani报错?抽烟钱;//undefindsmoke//undefind(好像明白了什么。。。)别着急,我们看windowwindow.information();//“未定义的香烟订单号:994857”恍然大悟,因为new可以不断给当前对象(Smoke)的this赋值【上面说了】,上面没有new相当于执行了Smoke()全局,所以它的this指向窗口!如何避免这种空操作?我们在Smoke内部执行类型检查:varSmoke=function(id,name){varnum=0;函数checkID(){返回真值};//执行时判断this是否属于Smoke,如果是newPassed0.0if(thisinstanceofSmoke){this.id=id;this.setName=function(name){this.name=name;}this.getName=function(){返回this.name;}//对象的公共属性(需要new)this.information=function(){//checkID()只能在Smoke内部调用if(checkID())returnthis.name+'cigarette'+'ordernumber:'+this.id}}else{returnnewSmoke(id,name);//在里面更新一个新的0.0}}看完觉得爽是不是感觉自己在写java。其实javascript在这里很灵活。这只是javascript中常用的面向对象设计模式。后面我会介绍更多的设计模式。这些设计模式都是前人给我们总结出来的。是的,我们为什么不使用它呢?感谢【他其实很爱吃虫】对本文的校对。如果你觉得还不错,可以关注我,继续看我的文章。大方向:前后端语言设计模式,如何设计框架,源码指导,技术实践青年有才的可以进群交流:147255248