首先我确实不清楚执行结果为什么会是这样,也许涉及到了运算符的优先级及 js 下怪异的隐式类型转换,但这些都不重要,重要的是,这个代码有什么意义?
如果没有意义,而又觉得无趣,那也没有研究的必要了。
如果它是有意义的,而且是项目里某项重要逻辑的一部分,那它是否伴有清晰的注释解释其工作原理及这样写的必要性?
回到题目本身,在写代码时,我们需要经常反省:“我写的代码我的同事们能看懂么?”
这是我近两年多时间,经历数个十人以上参与维护的项目后反问自己的问题。
曾经,我也是下面这些写法的拥趸:
// 交换两数,结果 a: 15 b: 10
let a = 10
let b = 15
a ^= b
b ^= a
a ^= b
// 判断存在子串
if (~"hello".indexOf("h")) {
// do something
}
// 交换 0 1
let a = 1;
// in some loop
{
a ^= 1;
console.log(a); // 0,1,0,1,0 ...
}
// 嵌套三目运算符或逻辑运算符
const a = condition1 ? 1 : condition2 ? 2 : 3;
const b = x || y && c && d || e;
// ...
但在看了其他人更多奇奇怪怪的「短小精悍」代码之后,我下定决心自己不再写这样的代码,而且在后面的 code review 中也坚决打回这类自以为是的写法,为什么呢?
代码是写给人看的
这话无论是对维护个人代码还是参与团队协作同样适用:
* 你是否被数月前甚至数星期前自己写的代码困扰过
* 你的同事是否经常跑来问你某个逻辑之前为什么要那样实现
所以,代码首先是写给人看的,其次才是给机器运行的,我们产出的代码,生命周期短则数月、长则数年,会被一批又一批人阅读、修改,如果净整些奇技淫巧,那公司、项目确实「离不开」你,而另一方面,别人也再难以与你展开合作了。
代码的意义应该不言自明
优秀的代码,应该是自说明的,也就是不需要注释也能明白其目的,举个最简单的例子,如下代码没写注释你一定能明白其意义:
let result;
if (isA()) {
result = doSomthingA()
} else if (isB()) {
result = doSomethingB()
} else {
result = doSomethingC()
}
而写成这样,代码行数确实变少了,但却很难一眼看明白了,而且极易改出 bug:
let result = isA() ? doSomthingA() : isB() ? doSomethingB() : doSomethingC()
追求代码以最小的行数实现在大部分情况下是无意义,毕竟我们不是在参加《一行代码可以做什么?》
做让人看得懂的架构
私以为,架构是用来做「约束」的。
如果设计的架构不能很好的约束参与开发项目的其他人,那至少应该不遗余力的主动推销自己的设计,让人遵循「设计约定」,如果他、她、Ta 都不遵守,那这个架构终会成为项目的负担。
为已有的架构引入新的特性也是同样的道理,首先要考虑的是解决什么问题,其次与再其次要考虑的都是它的理解心智是不是够低、使用成本是不是够低,过高的理解心智与使用成本,依然强按头让人家用,人家也不愿意用,结局与上例无异。
移除某架构特性的成本远高于移除某个 feature
结论
写代码不是:走自己的路让别人去说吧,或者走自己的路让别人无路可走。
软件工程,首先是工程,其次才是软件、是代码。软件工程少不了团队协作,避不开:
* 改别人的代码
* 别人改我的代码
* review 别人的代码
* 别人 review 我的代码
* …
高效的协作沟通就是尽可能“避免沟通”,用共同的语言:「编程语言」达成信息交换。
举双脚赞成!
每次都用不同的名字