尽管糟糕的代码也能运行,但如果代码不整洁,会是整个开发团队泥足深陷,写得不好的代码每年都要耗费无数的时间无精力。——《代码整洁之道》
说到代码整洁,代码之美,代码质量,代码规范,真正的是老生常谈。
为什么说真正的是老生常谈,因为这是一个作为一只老鸟必须要关注的问题,也会是老鸟之间交谈的大部分内容。
而作为一只新手菜鸟,他们往往在功能的实现上就耗费了开发的大部分时间,只剩下了小部分的时间可以去关注代码写得好不好的本身,甚至直接实现功能就万事大吉了。
当然这里并不是要去责怪什么,毕竟每只老鸟都是从菜鸟进化而来的。
突然想起一句话:世界上本无大神,只是填的坑多了就成了大神。(大伙儿尽可会心一笑 -:)
好了,书归正传。
本文主要以ionic1的代码作为演示,但是整个的思路也可适用于其他开发语言。
慎用scope作为参数
一般来说,其实并不建议直接将scope作为参数传入方法之中。
scope是view和controller交互的管道,上面承载了太多的信息,包含视图层的模板信息以及模板要加载的数据信息以及其他的一些内容。
在封装方法的时候,如果参数直接传入的是scope,我们在一开始的时候并不能知道究竟是使用或者操作scope上的什么东西。
我们在做封装的时候,要符合一个原则:单一职责原则。
如果这个方法需要的是一个数组[],请传入一个数组作为参数;如果需要的是一个对象{},请传入一个对象。
当然,我们也有参数需要传入scope的时候,比如使用modal的时候。
当我们对使用modal的逻辑代码进行再封装时,就需要传入scope。但是modal也不建议直接对scope上的数据进行使用操作,最好还是用一个新的形参给到modal。
隔离directive的scope
封装directive的时候,也是有scope参数的。
如果不给directive的scope赋值,那么它将直接使用父级的scope作为自己的scope,它可以直接使用父级scope上的所有变量和方法。
如果对directive的scope赋值之后,它将只能使用自己的scope。
要使用的父级scope的数据也用一个新的形参传给directive,这样就能达到隔离数据的效果,防止父级scope的数据在directive中被污染。
慎用angular.foreach()
我们都知道,foreach是无法被break出去的。
如果我们是对被遍历的对象或者数组里面的每一个元素都要进行操作,那么用foreach无疑效率是最高的。
但是,如果我们是要在满足某个特定条件时break条出循环,那么这个时候最好的做法就是用fori或者forin。
我们来看两段代码,第一段用foreach来实现。
我们可以看出,就算满足了第二个if的条件,也就是第一个if判断里的代码不再执行而已,但是整个循环还是依然会执行下去,直到遍历完整个数组。
var someFunc = function(arr) {
var allSelected = true;
angular.foreach(arr, function(data) {
if (allSelected) {
if (!data.selected) {
allSelected = false
}
}
});
return allSelected;
};
第二段代码我们用fori来实现,当满足条件的时候,我们直接break跳出循环。
var someFunc = function(arr) {
var allSelected = true;
for(var i = 0; i < arr.length; i++) {
var data = arr[i];
if (!data.selected) {
allSelected = false;
break;
}
}
return allSelected;
};
擅用return
第一种,在做ifelse判断的时候使用。
改造前的代码:
var doSometing = function(status) {
if (status === 1){
// 状态正确,do something
xxx bala bala...
return true;
} else if(status === 0) {
alert("状态错误!");
return false;
}
}
改造建议:
- 看方法名称,应该只是一个做某个特定事情的方法,不需要bool值作为返回
- if语句块里有return,如果满足条件,它将直接不执行return以后的语句了,所以else看着就比较多余了
- if(status===0)里面的代码更加简单,应该提到前面去,由易到难,这样才是比较符合人类做事情的顺序。
改造后的代码:
var doSometing = function(status) {
if(status === 0) {
alert("状态错误!");
return ;
}
if (status === 1){
// 状态正确,do something
xxx bala bala...
return;
}
}
第二种,作为方法的返回值
我们先看一段代码:
$scope.allProductSelected = false;
var isAllProductSelcted = function(products) {
var allSelected = true;
angular.foreach(products, function(product) {
if (allSelected) {
if (!product.selected) {
allSelected = false
}
}
});
$scope.allProductSelected = allSelected;
}
改造建议:
- 尽量解耦,可以不在方法中直接操作scope上的数据就不要直接操作了
- 看方法名称,这是一个需要有一个bool值作为返回的方法
改造后:
$scope.allProductSelected = false;
var isAllProductSelcted = function(products) {
var allSelected = true;
for(var i = 0; i < products.length; i++) {
var product = products[i];
if (!data.selected) {
allSelected = false;
break;
}
}
return allSelected;
}
$scope.allProductSelected = isAllProductSelcted(productList);
暂且就写到这儿了。
说到底,代码整洁,代码规范都是为了把代码写好,方便自己阅读,方便他人阅读,方便后期维护。
这是一种意识,一种每个程序员都该有的,都可以培养的意识。