编写可维护的js
不知道身为前端er的你有没有过这种体验,几个月前写的代码自己某天回头再看,如果没有详细的注释,发现已经看不懂了,不知道到底是干嘛的了。
如果没有这种体验,那一定有过另一种体验:同事之前写的代码有些没有注释,完全看不懂。
所以说编写可维护的代码为什么要单独开一篇文章说明,就是因为它太重要了,甚至比如果编写js还重要。
今儿就把自己学习到的记录下来,时不时的查阅,看看自己到底有没有做到,也算是一种养成良好习惯的磨练吧。
避免使用全局变量
这点就没什么好说的了。如果你是一个合格的前端er,你就会知道命名冲突究竟是多少蛋疼的事了。
如何访问全局对象
我猜看到这里第一反应应该就是window吧,但是如果我的运行环境不是浏览器呢,这下又怎么办?
最好的办法应该是通过一段自执行的函数返回:1
2
3var global = (function () {
return this;
}());
当然,很明显,严格模式下这段代码并不能返回你想要的结果(严格模式下函数的this指向undefined)
单var形式
这个形式有几个优点:
- 提供了一个单一的地方去寻找功能所需要的所有局部变量
- 防止变量在定义之前使用的逻辑错误
- 少代码(类型啊传值啊单线完成)
当然现在ES6出了let和const,有了块级作用域,为了防止变量提升,用let或const会比较好。
(不过使用时需要注意它们的暂时性死区)1
2
3
4
5
6
7
8
9function func() {
let a = 1,
b = 2,
sum = a + b,
myobject = {},
i,
j;
// function body...
}
for循环
for循环大家都懂,但是按照书中的说法,如果简单使用var i=0;i>something.length;i++
,每次循环都会去找一个something,如果只是简单数组还好,如果循环的是DOM,那就非常糟糕了,要知道不论什么时候,使用DOM都是非常昂贵的。
再者是i++写法,JSLint推荐使用i+=1,解释是“避免过分棘手(excessive trickiness)”
所以完整下来应该就是:1
2
3for(let i=0,max=something.length;i<max;i+=1){
//something[i]...
}
for-in枚举
该方法用于对象的枚举,虽然数组也可以使用此方法(数组也是对象),但并不推荐,原因是:
如果数组对象已被自定义的功能增强,就可能发生逻辑错误。另外,在for-in中,属性列表的顺序(序列)是不能保证的。所以最好数组使用正常的for循环,对象使用for-in循环。
对象的循环本没有什么可说的,但是有个非常强大的东西——原型链,对象会继承原型链下的属性和方法,但常常我们不需要这些属性和方法,于是hasOwnProperty()方法就非常有用了,它:
函数用于指示一个对象自身(不包括原型链)是否具有指定名称的属性。如果有,返回true,否则返回false。
1 | //第一种使用 |
如果结合单var形式,写成这样是最优的:1
2
3
4
5
6let i, hasOwn = Object.prototype.hasOwnProperty;
for (i in man) {
if (hasOwn.call(man, i)) { // 过滤
console.log(i, ":", man[i]);
}
}
使用switch
可以通过类似下面形式的switch语句增强可读性和健壮性:1
2
3
4
5
6
7
8
9
10
11
12var inspect_me = 0,
result = '';
switch (inspect_me) {
case 0:
result = "zero";
break;
case 1:
result = "one";
break;
default:
result = "unknown";
}
switch不仅能让代码看起来简洁,而且非常高高效。
命名
具体的请参阅这篇文章
这里只大概列举几点:
- 驼峰式命名
- 变量名以名词开头
- 方法名以动词开头
- 常量全部大写
- 构造函数以大写字母开头
其它
以前有写过一个关于写js的一些规范或者说是自己看完一些文章后的沉思吧,也一并放出来分享了。
一段好的代码应该是怎样的?
试想,当你在学一个业务代码的时候,你是否想过如果参数不是我想要的会怎样、如果出现了异常错误会怎样、如果突然要改需求了会怎样、如果这个参数不存在会怎样,我想都是没有的,你只是关注了结果,却始终没有考虑过边界状态,没有考虑过异常、兼容性以及校验,这很糟糕,非常糟糕。
所以一段好的代码应该是怎样的呢?
1.可用
必须确保自己写的代码是可以正常运行并得到想要的结果的,否则那就是无效代码.
2.健壮
①当存在参数或需要用户输入时,是否判断参数、用户输入存在?
②当参数或用户输入不符合要求时,是否做处理?
③当你使用的方法可能在别的浏览器不兼容时,是否做处理?
3.可靠
是否在所有情况下都能输出一个可靠的值?
4.宽容
①是否有足够的注释,让其他开发人员读懂?
②是否能在需求更改时快速更改而不需要大动干戈?
③当参数或用户输入不符合要求时,是否能将其转成可用参数?
一个例子
要求:编写一个javscript函数 fn,该函数有一个参数 n(数字类型),其返回值是一个数组,该数组内是 n 个随机且不重复的整数,且整数取值范围是 [2, 32]。
代码: