通常说代码可维护就意味着它具备以下的特点:
要想让代码容易维护,首先必须使其可读。代码缩进是保证可读性的重要基础,如果所有人都是用相同的缩进,整个项目的代码就会更容易让人看懂。缩进通常使用空格数而不是tab键来定义,因为tab键在不同文本编译器中的显示不同,一般来说缩进是4个空格。
可读性的另一方面是代码注释。在大多数的编程语言中,广泛接受的做法是为每个方法都编写注释。
一般来说,以下地方应该写注释:
代码中变量和函数的适当命名对于其可读性和可维护性至关重要。
只要应用程序的某个部分对另一部分依赖的过于紧密,代码就会变得紧密耦合,因而难以维护。
典型的问题是在一个对象中直接引用另一个对象,这样,修改其中一个,可能必须还得修改另一个。紧密耦合的软件难以维护,肯定需要频繁的重写。
web开发中最常见的耦合是HTML和JavaScript,在网页中,HTML和JavaScript分别代表不同层面的解决方案,HTML是数据,JavaScript是行为。这是因为它们之间要相互操作,需要通过不同的方式将这两种技术联系起来。可惜的是,其中一些方式会导致HTML与JavaScript紧密耦合。
把JavaScript直接嵌入在HTML中,要么使用包含嵌入代码的
<!-- 使用<script>造成紧密耦合 -->
<script>
document.write("hello 哪吒编程");
</script>
<!-- 使用事件处理程序属性造成紧密耦合 -->
<input type="button" value="Click me" onclick="dosomething()"/>
虽然技术上这样做没有问题,但实践中,这样会将表示数据的HTML与定义行为的JavaScript紧密耦合在一起,理想情况下,HTML和JavaScript应该完全分开,通过外部文件引入JavaScript,然后使用DOM添加行为。
一般来说,应该避免在JavaScript中创建大量的HTML。同样,这主要是为了做到数据层和行为层各司其职,在出错时更容易定位问题所在。
web应用程序的另一层是CSS,负责页面样式显示、
JavaScript和CSS紧密相关,都构建咋HTML之上,因此经常一起使用。
CSS和JavaScript紧密相连的例子:
element.style.color = "red";
element.style.backgroundColor = "blue";
每个web应用程序中都会有大量事件处理程序在监听各种事件。可是,其中很少能做到应用程序逻辑与事件处理程序分离。
以下是解耦应用程序逻辑和业务逻辑时应该注意的几点:
1、尊重对象所有权
2、不声明全局变量
最多可以创建一个全局变量,作为其他对象和函数的命名空间。
3、不要比较null
4、使用常量
随着作用域链中作用域数量的增加,访问当前作用域链外部变量所需要的时间也会增加,访问全局变量始终比访问局部变量要慢,因为必须遍历作用域链,任何可疑缩短遍历作用域链时间的举措都能提升代码性能。
改进代码性能非常重要的一件事,可能就是要提防全局查找。全局变量和函数相比于局部变量始终是最费时间的,因为需要经历作用域链查找。
如果for循环中多次引用document,可以通过在局部作用域中保存document对象的引用,能够明显提升这个函数的性能,因为只需要作用域链查找。
在性能很重要的代码中,应避免使用with语句,与函数类似,with语句会创建自己的作用域,因此也会加长其中代码的作用域链。在with语句中的diamagnetic一定比在它外部执行的代码慢,因为作用域链查找时多一步。
循环时编程中常用的语法构造,因此在JavaScript中十分常见,优化这些循环时性能优化的重要内容,因为循环会重复多次运行相同的代码,所以运行时间会自动增加。
因为每次循环都会计算终止条件,所以它应该尽可能地快。
循环体是最花时间的部分,因此要尽可能优化。要确保其中不包含可以轻松转移到循环外部的密集计算。
最常见的循环时for和while循环,这两种循环都属于先测试循环。do-while就是后测试循环,避免了对终止条件初始化评估,因此会更快。
如果循环的次数是有限的,那么通常抛弃循环而直接多次调用函数会更快。
JavaScript代码语句的数量影响执行的速度。一条可以执行多个操作的语句,比多条语句中每个语句执行一个操作要快。那么优化的目标就是寻找可以合并的语句,以较少整个脚本的执行时间。
任何时候只要使用迭代性值(递增或者递减),都要尽可能使用组合语句。
比如
let name = values[i++]
替代
let name = values[i];
i++;
在所有JavaScript代码中,涉及DOM的部分无疑是非常慢的。DOM操作和交互需要占用大量时间,因为经常需要重新渲染整个或部分页面。此外,看起来简单的操作也可能花费很长时间,因为DOM中携带着大量信息。理解如何优化DOM交互可以极大地提升脚本的执行速度。
访问DOM时,只要访问的部分是显示页面的一部分,就是在执行实时更新操作。之所以称其为实时更新,是因为涉及立即更新页面的显示,让用户看到。每次这样的更新,无论是插入一个字符还是删除页面上的一个内容,都会导致性能损失。这是因为浏览器需要为此重新计算数千项指标,之后才能执行更新。实时更新的次数越多,执行代码所需的时间也越长。
在页面中创建新DOM节点的方式有两种,使用DOM方法如createElement()和appendChild(),以及使用innerHTML。对于少量DOM更新,两种技术区别不大,但对于大量DOM更新,使用innerHTML要比使用标准DOM方法创建同样的结构快得多。
在给innerHTML赋值时,后台会创建HTML解析器,然后使用原生DOM调用,而不是JavaScript的DOM方法来创建DOM结构,原生DOM方法速度更快,因为该方法时执行编译代码而非解释代码。
大多数web应用程序会大量使用事件处理程序实现用户交互。一个页面中事件处理程序的数量与页面响应用户交互的速度有直接关系,为了减少对页面响应的影响,应该尽可能使用事件委托。
事件委托利用了事件的冒泡,任何冒泡的事件都可以不在事件目标上,而在目标的任何祖先元素上处理。基于这个认知,可以把事件处理程序添加到负责多个目标的高层元素上。只要可能,就应该在文档级添加事件处理程序,因为在文档级可以处理整个页面的的事件。
由于web应用程序存在很大的性能问题,只要访问HTMLCollection,无论是它的属性还是方法,就会触发查询文档,而这个查询相当耗时,减少访问HTMLCollection的次数可以极大地提升脚本的性能。
可以优化HTMLCollection访问最关键的地方就是循环。