写JS代码差不多也有两年了吧,从刚开始的“初生牛犊不怕虎”乱写一通到后来也慢慢知道去规范一下自己写的代码。这种感觉就像是代码是你的作品,你希望它保持一份不仅干净而且也优雅的姿势。所以后来慢慢规范了自己写的代码,再后来觉得仅仅规范自己的代码还不行,这个团队其他人的也需要保持一致,再再后来就开始尝试写了一份代码规范,用于规范团队的代码质量。网上有不少讲代码规范的书,我也就不再献丑了,大家可以去看看阿里\百度\腾讯他们的代码规范,写的非常不错。我就仅仅把自己遇到的尝试做一下总结,这些可能别人也总结过无数次了,欢迎吐槽交流,也希望对你有点儿帮助。
1、减少全局污染
我们都知道javascript使用function来管理自己的作用域,一个定义在函数内的变量对外是不可见的,这有点类似于其它语言里的私有变量。对于javascript的执行环境来说一般都有一个全局变量,在所有的函数外可以用this来指引,例如在浏览器端是window。但是当过多的在全局执行环境下定义变量会造成各种苦逼的事情,比方说你定义的变量被其他人定义的同名变量覆盖掉,或者你未来定义的变量把你过去定义的同名变量也覆盖掉,而且过多的全局变量放在执行对战里还会造成内存的浪费等等不优化的情况发生。我就不再具体讲没个苦逼的事情是如何苦逼了,仅仅讲讲可能会导致这种情况发生的不好的示例吧。
①声明变量忘记使用“var”的情况。
1 2 3 4 5 6 7 |
var sample = function () { var a1 = "hello"; a2 = "world"; }; sample(); alert(a1);//undefined alert(a2);//world |
如你所见,a2因为忘记使用var导致了它成为了全局的变量,这样就有可能造成其它地方的修改覆盖它或者将其它地方的变量覆盖等(忘记var也会使得该变量可以delete)。正确的做法是,所有的变量都使用“var”,并且尽量都生命在函数体的头部,这样一目了然。如下:
1 2 3 4 5 6 |
var sample = function () { var a1 = true,//标识位1 a2 = true, //标识位2 a3 = false;//标识位3 //do some logic }; |
(注:用“,”号隔开变量可以避免过多使用”var”。)
②变量名提升。
javascript中函数内所有使用var声明的变量都会提升到函数体头部,这也是很多人容易犯错的一点。具体来讲就是:
1 2 3 4 5 6 7 |
myname = "global"; function sample() { alert(myname); // "undefined" var myname = "local"; alert(myname); // "local" } sample(); |
如你所见,第一个alert出来的并非global。原因在于,函数sample内部声明的myname会提升到函数体顶部,而原语句的地方才是正在赋值的地方。在声明和赋值直接引用的话肯定是undefined了。其执行效果如下:
1 2 3 4 5 6 7 8 |
myname = "global"; function sample() { var myname;//没有赋值 alert(myname); // "undefined" myname = "local";//此处赋值 alert(myname); // "local" } sample(); |
所以一个重要的经验就是,在函数体讲所有的var声明的东西都拿到函数体顶部,以免造成不必要的错误。
2、for循环。
我们习惯将for循环写成如下形式:
1 2 3 |
for (var i = 0; i < myarray.length; i++) { //logic } |
看似没有问题,但是如果myarray是读取的DOM的节点,那么每一次循环都要去DOM里选取节点再做判断,非常影响性能。可能数量不大感觉不错来,多了就非常严重了。所以,for循环判断条件里尽量不要使用涉及到DOM操作的动作。优化如下:
1 2 3 |
for (var i = 0, max = myarray.length; i < max; i++) { // logic } |
另外一个就是使用for-in循环对象的话会读取对象从原型链里的属性,如果这不是希望的,那么可以用一个判断hasOwnProperty(i)去掉它。
3、用“===”取代“==”
前者是严格判断,后者会提前进行隐式的类型转换。
4、不使用eval()
5、统一缩进大小(无论用tab或者2个或者4个空格,团队统一即可),任何用花括号括起来并换行的都进行缩进。
6、花括号{}
for循环或者if判断等,即使只有一行,也要换行并用{}括起来。
7、空格
任何“;”后空一格、for循环中初始化“,”后空一格、数组中”,”后空一格、对象中“:”后空一格、如:
1 2 3 4 |
for (var i = 0, j = 1; i < 10; i += 1){ var some = [1, 2, 3]; var obj = {aa: 1, bb: 2} } |
函数参数里“,”后空一格、函数声明中花括号前空一格、函数表达式中括号前后各空一格,如:
1 2 3 |
func(a, b, c){}; function func() {}; var func = function () {}; |
所有的操作符前后都跟一个空格,如:
1 2 3 4 5 6 |
var d = 0, a = b + 1; if (a && b && c) { d = a % c; a += d; } |
8、命名规则
构造器函数首字母大写,如:
1 |
function Person() {...} |
变量用驼峰式,如:
1 |
getFirstName() |
常量全用大写字母,如:
1 |
var PI = 3.1415926; |
私有函数用下划线开头,如:
1 2 3 4 5 6 7 8 |
var person = { _setSext: function () { // ... }, _setName: function () { // ... } }; |
9、写注释
这一步非常关键,因为你写的代码别人不一定看得懂,你写的将来你也不一定轻易能看懂。所以良好的注释习惯可以事半功倍。
感谢你这么大的耐性,天马行空的对着自己写的代码总结了一点儿,希望多少对你有点启发。