1、烂代码是怎么定义的?
!KissyUI是淘宝Kissy这个前端项目的一个群,龙藏同学在看完我在公司内网的“读烂代码系列”之后就在群里问呵:烂代码是怎么定义的?
是呵,到底什么才算烂代码呢?这让我想到一件事,是另一个网友在gtalk上问我的一个问题:他需要a,b,c三个条件全真时为假,全假时也为假,请问如何判断。
接下来KissyUI群里的同学给出了很多答案:
en… 确实,我没有完全验证上面的全面答案的有效性。因为如同龙藏后来强调的:“貌似我们是要讨论什么是烂代码?”的确,我们怎么才能把代码写烂呢?上面出现了种种奇异代码,包括原来提问者的那个取巧的:
因为这个问题出现在js里面,存在弱类型的问题,即a、b、c可能是整数,或字符串等等,因此(a+b+c)%3这个路子就行不通了,所以才有了
2、问题的泛化与求解:普通级别
如果把上面的问题改变一下:
– 如果不是a、b、c三个条件,而是两个以上条件呢?
– 如果强调a、b、c本身不一定是布尔值呢?
那么这个问题的基本抽象就是:
对于这个e_xor()来说,最直接的代码写法是:
// v1,扫描所有参数,发现不同的即返回true,全部相同则返回false。
function e_xor() {
var args=arguments, argn=args.length;
args[0] = !args[0];
for (var i=1; i<argn; i++) {
if (args[0] != !args[i]) return true;
}
return false;
}
接下来,我们考虑一个问题,既然arguments就是一个数组,那么可否使用数组方式呢?事实上,据说在某些js环境中,直接存取arguments[x]的效率是较差的。因此,上面的v1版本可以有一个改版:
这段小小的代码涉及到splice/slice的使用问题。因为操作的是arguments,因此splice可能导致函数入口的“奇异”变化,在不同的引擎中的表现效果并不一致,而slice则又可能导致多出一倍的数据复制。在这里仍然选用slice()的原因是:这里毕竟只是函数参数,不会是“极大量的”数组,因此无需过度考虑存储问题。
3、问题的泛化与求解:专业级别
接下来,我们既然在args中得到的是一个数组,那么再用for循环就实在不那么摩登了。正确的、流行风格的、不被前端鄙视做法是: