编写可维护的代码很重要,因为大部分开发人员都话费大量实践维护他人代码。很难从头开始开发新代码的,很多情况下是以他人成果为基础的。确保自己代码的可维护性,以便其他开发人员在此基础上更好的开展工作。
代码约定是一种让代码变得可维护的简单途径是形成一套JavaScript代码的书写约定。
可读性:要让代码具有可维护性,首先他必须可读。可读性的大部分内容都是和代码缩进相关的,还有一方面是注释。包括以下几个方面:
命名规则如下:
变量名应为名词如car或person 函数名应以动词开始,如getName()。返回布尔值的函数以is开头,如isEnable() 变量名和函数都应使用合乎逻辑的名字,不要担心长度。长度可以通过后处理和压缩来缓解有三种方式表明变量数据类型的方式:
初始化:当定义一个变量后,它应该被初始为一个值,来暗示它将来如何应用。var found/*:Booldan*/=false;
类型注释的缺点是你不能使用多行注释一次性注释大块的代码,因为类型注释也是多行注释,两者会冲突。
只要应用的某个部分过分依赖于另一部分,代码就是耦合过紧、难于维护。典型的问题如:对象直接引用另一个对象,并且当修改其中一个的同时需要修改另外一个。紧密耦合的软件难于维护并且需要经常重写。
html和javascript各自代表了解决方案中的不同层次:html是数据,javascript是行为。因为他们天生就需要交互,所以有多种不同的方法将这两个技术关联起来。
情况一:直接写在html中的javascript,使用包含内联代码的
<script>
元素或者使用Html属性来分配事件处理程序,都是过于紧密的耦合。
比如:
从技术上说都是正确的,但是在实践中,它们将表示数据的html和定义行为的JavaScript紧密耦合在了一起。**理想情况是:**html和JavaScript应该完全分离,并通过外部文件和使用DOM附件行为来包含JavaScript。
当两者耦合在一起时,出现javascript错误时就要先判断错误出现在Html部分还是javascript文件中。还会引入和代码是否可用的相关问题。
情况二:
html和javascript的机密耦合也可以在相反的关系上成立:javascript包含了Html.这通常会出现在使用innerHtml来插入一段Html。
将html和JavaScript解耦可以在调试过程中节省实践,更加容易确定错误的来源,也减轻维护的难度,更改行为只需要在JavaScript文件中进行,而更改标记则只要在渲染文件中。
另外一个web层则是css,它主要负责页面的显示。
最常见的紧密耦合例子是使用javascript来更改某些样式,如下所示:
//css对javascript的紧密耦合 element.style.color = "red"; element.style.backgroundColor = "blue";
由于CSS负责页面的显示,当显示出现问题时应该只是查看CSS文件来解决。然而,当使用了JavaScript来更改某些样式的时候,如上面代码所示,就出现了第二个可能已更改的和必须检查的地方。结果是JavaScript也在某种程度上负责了页面的显示,并与CSS紧密耦合了。如果将来需要修改样式,CSS和JavaScript文件可能都需要修改,这会给维护人员带来噩梦。
解耦合的原则:
虽然不可能完全将css和javascript解耦,但是还是能让耦合更松散的,这是通过动态改变样式类而非特定样式来实现的,如下所示:
//css对javascript的松散耦合 element.className = "edit";
通过只修改某个元素的css类,就可以让大部分样式信息严格保留在css中。JavaScript可以改变样式类,但并不会直接影响到元素的样式,只要使用了正确的类,那么任何显示问题都可以直接追溯到css而非JavaScript。
第二类紧密耦合仅会在IE中出现(标准模式下的IE8不会出现),它可以在css中通过表达式嵌入javascript,例如:
/*javascript对css的紧密耦合*/ div{ width:expression(document.body.offsetwidth-10+"px"); }
通常要避免使用表达式,因为他们不能跨浏览器兼容,还因为它们所引入的JavaScript和css之间的紧密耦合。
好的层次划分是非常重要的。显示问题的唯一来源应该是css,行为问题的唯一来源应该是javascipt.在这些层次之间保持松散耦合可以让你的整个应用更加易于维护。
很少有能仔细得将应用逻辑从事件处理程序中分离的。例如:
fuction handleKeyPress(event){ if(event.keyCode == 13){ var target = eventUtil.getTarget(event); //应用逻辑部分 var value = 5 * parseInt(target.value); if(value >10){ document.getElementById("error-msg").style.display = "block"; } } }
这段代码除了包含应用逻辑,还进行了事件的处理。
这种方式的问题有其双重性:首先,除了通过事件之外就再没有方法执行应用逻辑,让调试变得困难。如果没有发生预想的结果怎么办?是不是表示事件处理程序没有被调用还会死指应用逻辑失败?其次,如果一个后续的事件引发同样的应用逻辑,那就必须复制功能代码或将代码抽取到一个单独的函数中。无论如何,都要做比实际所需更多的改动。
较好的方法是将应用逻辑和时间处理程序分离,这两者分别处理各自的东西。一个事件处理程序应该从事件对象中提取相关信息,并将这些信息传送到处理应用逻辑的某个方法中。例如前面的代码重写为:
//处理应用逻辑 function validateValue(value){ var value = 5 * parseInt(value); if(value >10){ document.getElementById("error-msg").style.display = "block"; } } //事件处理函数 fuction handleKeyPress(event){ if(event.keyCode==13){ var target = EventUtil.getTarget(event); validateValue(target.value); } }
好处:从事件处理程序中分离应用逻辑有几个好处。首先,可以让你更容易更改触发特定过程的事件。如果最开始由鼠标点击事件触发过程,但现在按键也要进行同样处理,这种更改就很容易。其次,可以在不附加到事件的情况下测试代码,使其更容易创建单元测试或者是自动化应用流程。
以下是要牢记的应用和业务逻辑之间松散耦合的几条原则:
牢记着几条可以在任何代码中都获得极大的可维护性的改进,并且为进一步的测试和开发制造了很多可能。
</script>