代码基本原则和优化技巧
目标: 让代码更可读,而不是让代码性能更高。 某些时候为了让代码性能更高,但是却更不可读了
基本原则
- 易读性, 性能瓶颈往往是网络
- 如果不是性能瓶颈,就不要为了性能而改写代码
for(let i = 0; i < array.length; i++) { doSomething() } for(let i = 0, l = array.length; i < l; i++) { doSomething() } // 前后并不会使代码突破性能瓶颈
- 复杂性守恒原则: 无论你怎么写代码,复杂性都是不会消失的
如果逻辑很复杂,那么代码看起来就应该是复杂的。反之如果逻辑很简单,代码也应该是简单的
最基础的变量命名规范
程序员三大难题
- 变量命名
- 缓存失效
- 循环边界(+1 -1 < <= 的问题)
注意词性
- 普通变量、属性用[名词]
person = { name: 'xxx', grade: '2' }
- bool变量、属性用[形容词]或者[be动词]或者[情态动词]或者[hasX]
person = { dead: false, canSpeak: true, isVip: true }
- 普通函数、方法用[动词]开头
person = { run(){}, drinkWater(){} }
- 回调、钩子函数用[介词]开头,或用[动词的现在完成时态]
person = { beforeDie(){}, afterDie(){}, dead(){}, errorCaputred(){} } button.addEventListener('click', onButtonClick)
- 容易混淆的地方加前缀
$div2.addClass('active') domDiv1.classList.add('active')
- 属性访问器可以用[名词]
$div.text() // getText $div.text('xxx') // setText
如何写出无法维护的代码
引用一篇文章《如何写出无法维护的代码》, 毕竟你知道怎么写烂代码的时候,就知道好代码怎么出现的了。
如何写出无法维护的代码
- 什么叫“创造力”,创造力就是——就算是要干一件烂事都能干得那么漂亮那么有创意的能力。
- 什么叫“抓狂”,抓狂就是——以一种沉着老练的不屈不挠的一本正经的精神一点一点把你推向崩溃的边缘。
列出文章中比较普遍的命名问题:
- 有创意地拼写错误。比如:SetPintleOpening, SetPintalClosing。这样可以让人很难搜索代码。
- 抽象。比如:ProcessData, DoIt, GetData… 抽象到就跟什么都没说一样。
handleClick(){} // 谁在handle 谁在click onClickBuy(){} // good
- 缩写。比如用一些只有自己知道的缩写,能用的缩写只能是所有人都知道的缩写如html
- 不要同时出现长的很像的字母,如l1, O0
注意一致性
整个工程的代码一致性
介词一致性
如果你使用了 before + after ,那么在代码的所有地方都要坚持使用;
如果你使用了 before + 完成时,那么就坚持使用;
如果你改来改去,就[不一致]了,不一致将导致代码[不可预测];顺序一致性
比如updateContainerWidth和 updateHeightOfContainer的顺序就令人变扭,两者都没有问题,但是混用,同样引发了[不可预测]-
表里一致性
函数名必须完美体现函数的功能,既不能多也不能少getSongs = () => { return $.get('./songs').then(response => { div.innetText = response.songs }) } // 问题出在,你函数名为getSongs,却悄悄更新了div。 即表里不一 // getSongs() & updateDiv()
时间一致性
有可能随着代码的变迁,一个变量的含义已经不同于他一开始的含义了,这个时候需要及时改掉这个变量的名字。
这一条是最难做到的,因为写代码容易,改代码难,如果一个代码组织的不好,很可能会出现牵一发而动全身的情况。
最好的方式就是在项目开始就做好命名之类的规范,会比较好
如何改代码
如果你代码有单元测试,那么盖起来就很放心。如果没有单元测试,就需要使用[小步快跑]的策略来修改。
小步快跑: 每次只改一点点,测试通过后,再修改一点点,再修改一点点
使用函数来修改代码
- 将一小坨代码放到一个函数里
- 将代码依赖的外部变量作为参数
- 将代码的输出作为函数的返回值
- 给函数取一个合适的名字
- 调用这个函数并传入参数
- 这个函数里的代码如果超过5行,则依然有优化空间,可以拆成两个函数,请回到第1步
用对象来优化代码
如果使用了函数改造法改造后,发现有太多的小函数,则可以使用对象将这个函数串起来。
通过使用this,可以轻松的串联一个对象和所有函数。当然这需要this的基本功相对ok
表驱动编程(hash表)
一定程度上消除if else, 逻辑更直观
function howManyDays(month) {
if(month === 1 || month === 3 || month === 5 || month === 7 || month ===8 || month === 10 || month === 12) {
return 31
} eles if (month === 2) {
return 28
} else {
return 30
}
}
// 返回月份对应的天数
function howManyDays(month) {
vat table = {
1: 31,
2: 28,
3: 31,
4: 30,
5: 31,
6: 30,
7: 31,
8: 31,
9: 30,
10: 31,
11: 30,
12: 31
}
return table[month]
}
// 表编程后,if else消失了
一些Tips
- 把别人关心的东西放在显眼的位置,可以起到自说明的作用, 可以省去一些重复的注释
总结
这样的代码看起来总有一些不对劲,可以尝试改进
- 表里不一的代码
- 过时的注释,改了代码却没改注释
- 逻辑很简单,但是看起来很复杂的代码
- 重复的代码
- 相似的代码
- 总是一起出现的代码