可维护性有几点:
1.可理解性—其他人可以接手代码并能够理解他的意图和干什么用的,不需要原开发人员完整解释。
2.直观性—一看代码就能明白。
3.可适应性—当数据变化的时候不要求完全重写方法。
4.可扩展性—在代码架构上已考虑到未来允许对核心功能的扩展。
5.可调试性—当有地方出错时,代码能够给以你足够的信息来尽可能的确定问题所在。
以下有几个方面描述可维护性:
可读性
a.缩进是4个空格或者使用tab键
b.每个函数和方法上都应该包含一个注释,描述其目的和用到什么算法;用于完成单个任务的多行代码也要添加注释。
c.变量和函数命名时,能够通过名字就能知道其目的,返回布尔类型值得函数一般以is开头。如:isEnable()。松散耦合
a.解耦HTML/JavaScript。 直接写在HTML中的JavaScript,使用<script>
元素或者直接在元素上写事件处理程序都是紧耦合。如:
<script type="text/javascript">
document.write("Hello");
</script>
<input type="button" value="Click" onclick="something()" />
当出现错误时必须在html和JavaScript中判断。还有在JavaScript中写html如:
function test(args) {
var container = document.getElementById("container");
container.innerHTML = "<div class=\"me\"><p>a</p></div>";
}
html和JavaScript应该保持分离,使用JavaScript外部引用文件等等。
b. 解耦css/JavaScript。 紧密耦合的例子:
element.style.color = "red";
为了尽量将css和JavaScript解耦,一般使用动态更改类来实现,如:
element.className = "change";
c.解耦应用逻辑/事件处理程序。 例子:
function handleKeyPress(event) {
if(event.keyCode == 13) {
var target = event.target;
var value = 5 * parseInt(target.value);
if(value > 10) {
document.getElementById("msg").style.display = "block";
}
}
}
这件事件处理程序既有应用逻辑还有事件的处理,这样把两个合在一起有些问题:除了通过事件之外就在没有办法执行应用逻辑,这让调试变得困难; 如果没有出现预想的结果,问题是出在应用逻辑上还是事件处理上呢?; 如果其他事件也有同样的应用逻辑,就无法复用了。
因此应该把应用逻辑和事件的处理分离开来,让他们处理各自的任务。一个事件处理程序应该从事件对象中提取相关信息,并把这些信息传送到处理应用逻辑的方法中。如:
function checkValue(value) {
var value = 5 * parseInt(target.value);
if(value > 10) {
document.getElementById("msg").style.display = "block";
}
function handleKeyPress(event) {
if(event.keyCode == 13) {
var target = event.target;
checkValue(target.value);
}
}
checkValue()没有任何东西依赖于事件的处理,只是接收了一个值,并根据该值做相应的处理。
不要为实例或者原型添加属性或者方法,不要重新定义已存在的方法。不是你创建的对象或者维护的对象、方法,你就不要对它们进行修改。
避免全局变量。 一般是最多创建一个全局变量,让其他对象和方法存在其中。例子:
//两个全局变量——避免
var name = "Shen";
function sayName() {
alert(name);
}
这段代码有两个全局变量:name和函数sayName(),其实可以创建一个包含这两个对象的全局变量:
//一个全局变量——推荐
var MyName = {
name: "Shen",
sayName: function() {
alert(this.name);
}
}
- 避免与null进行比较。
JavaScript不做任何自动类型检查,由开发人员负责。最常见的类型检查就是查看某个值是否为null。但是,直接将值与null比较并不充分。例如:
function sortArray(value) {
if(value != null) {
value.sort(compar);
}
}
该函数的目的是为vaule数组进行排序。这里只检查了value是否为null,并没有判断它是否为数组,也有可能是字符串或者数字,就会导致错误。修改:
//推荐
function sortArray(value) {
if(value instanceof Array) {
value.sort(compar);
}
}
如果值为引用类型,使用instanceof检查;如果值为基本类型,使用typeof检查;如果希望对象包含某个方法名,使用typeof确保名字的方法存在于对象中。
- 使用常量。
JavaScript没有常量的概念,就是将数据从应用逻辑中分离出来的思想,可以在不引入错误的风险的同事,就改变数据。看例子:
function validate(value) {
if(!value) {
alert("Invalid value.");
location.href = "/errors/invalid.java";
}
}
这个函数有两个数据:显示给用户的信息和URL。显示用户的信息应该允许语言国际化,那么就需要随时改变,URL可能在未来有所改变,那么这两个数据应该抽取出来。如果在原函数中修改可能会修改函数中应用逻辑中的代码而出错。因此可以把数据抽取出来变成单独定义的常量。将逻辑与数据分离开来。例如:
var Constants = {
INVALID_VALUE_MSG: "Invalid value.",
INVALID_VALUE_URL: "/errors/invalid.java"
};
function validate(value) {
if(!value) {
alert(Constants.INVALID_VALUE_MSG);
location.href = Constants.INVALID_VALUE_URL;
}
}