写js也有那么段时间了,也看过几本关于js的书,从最初的《锋利的jquery》《高性能javasrcipt》到《javascript设计模式》等,虽然看了些书,看到了书中的各类理论与技巧,然而在实际的使用中,真正用到的倒是很少。javascript
js的面向对象与我所熟悉的c#等语言的面向对象稍有不一样,但基本都会有封装,继承,多态等。弱语言天生就具有多态性,没有类型检测的js相对而言能够作出许多强类型语言所作不到的灵活,虽然这不能说彻底没有坏处,但这个优点让js代码变得丰富多彩。java
程序的编写基本遵照一些原则,好比单一原则,开闭原则,迪米特原则等,js的也不例外。然而由于js的特殊性,不少时候随着需求的改变及代码量的增长颇有可能会变成面条式的代码,变的难以阅读,不易扩展,重复而且分散。这时候就不由的想要改变,想要重构。jquery
亡羊补牢,犹未为晚。c#
重构的目的是让程序更加健壮,即健壮性。符合基本原则,可扩展,可复用,易维护等。设计模式
那么怎样重构才能让程序更加健壮呢?隔离变化,抽象不变。让程序更符合基本原则。闭包
var outConding=function(result){ var outCond=1; var outConded=2; kinds={ kindItem:outCond, KindChildren:outConded }; cols=[{ value:outCond }]; }; var inConding=function(result){ var inCond=1; var inConded=2; kinds={ kind:inCond, Children:inConded }; cols=[{ price:inConded, value:inCond },{
price:inConded,
value:inCond
}];
}
outConding(res);
inConding(res);
上面代码是否健壮呢?很明显至少没有考虑到复用性及扩张性,若是以后须要添加onCoding,offCoding难道还须要将重复的代码在一次次写一遍吗?函数
那么这就须要完善了,对其重构。两段代码有明显的类似的地方,好比结构,拥有kinds,cols等。但也有不一样的地方,好比临时参数。如何将其抽离出来以符合健壮性呢?性能
var conding=function(result){ kinds={}, cols=[]; }
首先将不变的抽象出来,只留下基本结构。而后分析变化。问题来了,里面须要依赖临时变量,临时变量的变量名是未知的,数量是未知的,这该如何抽象出来呢?this
用重载能够吗?不行,变量在不变的程序里是未知的。那让不变的程序继承变化的父类呢?。。。好像能够,那来实现试试吧。spa
js有原型链能够模拟继承,让父类变的可变化,子类继承父类,子类中使用的变量在父类中声明,这就能够解决变量的未知性了。
写着写着,突然有个想法,不是有个更简单的方法吗?既然是弱语言为什么必定要用强语言的优点放弃本身的?
var conding=function(tempParams, kindsParam,colsParam, result){ var CondingParams=new tempParams(); kinds=kindsParam(CondingParams), cols=colsParam(CondingParams); };
js没有类型检测,那么我传个参数表示临时变量集合能够吗?固然能够。接下来就是可扩展,遵循单一职责原则,开闭原则,迪米特原则,完成如下代码。
var conding=function(tempParams, kindsParam,colsParam, result){ var CondingParams=new tempParams(); kinds=kindsParam(CondingParams), cols=colsParam(CondingParams); }; var outCondingInfo = { tempParams: function () { this.outCond = 1; this.outConded = 2; }, kindsParam: function (param) { return { kindItem: param.outCond, KindChildren: param.outConded } }, colsParam: function (param) { return [{ value: param.outCond }] } } var inCondingInfo = { tempParams: function () { this.inCond = 1; this.inConded = 2; }, kindsParam:function(param){ return { kind:param.inCond, Children:param.inConded } } , colsParam: function (param) { return [{ price: param.inConded, value: param.inCond }, { price: param.inConded, value: param.inCond }]; } } var res=1; conding(outCondingInfo.tempParams,outCondingInfo.kindsParam,outCondingInfo.colsParam,res) conding(inCondingInfo.tempParams,inCondingInfo.kindsParam,inCondingInfo.colsParam,res)
这个对于最初的代码,若是须要新增一个onCoding,只须要新增一个onCondingInfo的对象就能够了,是否是可扩展了?是否是相对而已面向对象了一点?
不过一味追求健壮性,面向对象,虽然不会成为面条式代码,但有可能在你不讲解的状况下,他人很难看懂你写的是什么,因而这就形成了阅读性,关联上下文内容等问题。这即是取舍的问题了。
还有一些重构的小技巧,好比只在一个方法内使用,其余地方使用不到的方法,尽可能不要单独写为一个全局函数,最好是直接在使用的方法内用一个临时变量存储他,尽可能不去污染全局。使用闭包让待执行的方法顺序执行,或限定执行完几个方法后在执行特定方法等。
若是有好的意见或好的技巧,欢迎分享,欢迎指点。