乐趣区

如何编写可维护的优雅代码

程序是写给人读的,只是偶尔让计算机执行一下。就执行而言,计算机只关心对错,但是就团队协作而言,风格一致且优雅的代码,会让人看上去赏心悦目(痛哭流涕)。因此,确定编码风格,就尤为重要

本文就 javascript 而言,对于使用 vue 等框架,使用 Eslint 或者团队已经强制推行自己的风格,仅供参考

缩进

4 个空格(制表符)

一般编辑器按下 tab 时,默认是 4 个空格。因此,小编推荐 4 个空格,至少看上去是最舒服的

推荐指数:????????

语句结尾

以;(分号)结尾

有赖于分析器的分号自动插入机制,js 代码省略分号也是可以正常工作的。就 JSLint 和 JSHint 而言,省略空格,都会有警号。还有更麻烦的是,如果 js 是下面这 5 个字符之一,js 就不会对上一行自动添加分号([/ + –

x = y
(function () {})()

便会等价于

x = y(function () {

})()

推荐指数:????????????????

空行

在编码规范中,空行是最容易忽视的一方面。而且,就编程人员而言,仁者见仁,智者见智。下面,小编就简单阐述一下自己的见解。

什么时候要有空行?

  1. 方法和方法之间
function getName () {// 代码块}   

function getAge () {// 代码块}

推荐指数:????????

  1. 变量和函数之间要空行
var name = null

function getName () {}

推荐指数:????????????????

  1. 在多行与上一行注释前
/*
    取得属性值 name
*/
var name = null

/*
    取得属性值 age
*/
var age = null

推荐指数:????????????

换行

当一行长度受到单行最大字符限制,或者一行过长影响代码阅读时,需要我们手动拆成多行。此时,我们需要在运算符换行,运算符写在上一行的末尾。

  1. 赋值

给变量赋值时,第二行应该与第一行赋值运算符后的变量对齐

var result = name + age + gender + 
             msg + like; 

推荐指数:????????

  1. 运算

运算符后进行换行,下一行会增加 1~2 个缩进。小编通常使用 1 个缩进

if (year == '2019' && month == '8' &&
  day == '23') {// 代码块}

推荐指数:????????

变量和函数

只要写代码,就在声明变量和函数,或者走在声明变量和函数的路上。因此,变量和和函数声明的可读性就至关重要。

变量

声明变量的长度要尽可能短,并抓住要点,且尽可能的体现数据类型。对于数组,一般采用 +s 的复数形式

/*
    好的做法
*/
var count = 1;
var name = 'jack'
var status = false 
var names = ['jack', 'john', 'dave']

/*
    不好的做法
    变量声明向函数,容易产生误解
*/
var getCount = 10
var getName = 'jack'
var isUse = false

推荐指数:????????????

函数

对于函数来说,第一个单词最好是动词,如 get, set, has, is, toggle, can, delete, update, insert, add 等,推荐使用驼峰明明法。函数的长度一定要见明知意,哪怕长度稍微长一点,都是值得的

/*
    好的做法
*/
function getName () {return name}

function checkPermissionsBySession () {}

推荐指数:????????????????

大括号

起首的大括号要跟在关键字的后面。因为 Javascript 会自动添加句末的分号,导致一些难以察觉的错误。为了避免这一类错误,需要写成下面这样

/*
    好的做法
*/
return {name: 'jack'}  

/*
    不好的走法
    解析器会解析 return ; 
    后面的代码就不会执行
*/
return 
{name: 'jack'}  

推荐指数:????????????????

圆括号

一般来说:所有 语法元素与左括号 之间,都有一个空格。下面这两种情况除外

  1. 调用函数的时候,语法元素和做括号之间,没有空格
  2. 函数名与参数序列之间,没有空格
/*
    好的写法
*/
if (a === b) {}    

for (let i=0; i<10; i++) {}

return (a + b)

function getName(arr) {

}
getName()

推荐指数:????????????

null 和 undefined

null

使用 null 的最好方式方式是看作一个 占位符 。而不是用 null 来检测是否 传参 ,或者检测是否 变量初始化

/*
    好的做法
*/
var name = null

function getName () {if (!condition) {return null}
}

/*
    不好的做法
*/
var name;
if (name != null) {

}

function getName(arg1, arg2) {if (arg3 != null) {}}

推荐指数:????????

undefined

没有被初始化的变量都有一个初始值,即 undefined

var age;
console.log(typeof age) // undefined

推荐指数:????????

‘==’ 和 ’===’, ‘!=’ 和 ’!==’

js 具有强制类型转换的机制,强制类型转换会驱使某些变量自动转换成其他不同类型。可能会造成意想不到的结果。虽然使用相等,在开发过程中可能会加快开发速度,但是一旦出现问题,排查起来花费的时间会多得多。因此,小编强烈建议使用全等和不全等

/*
  不好的做法
*/
console.log(1 == true) // true
console.log(0 == '')   // true

推荐指数:????????????

全局变量

确保你的函数不会对全局变量有依赖,这将增强您对代码的可测试性。尤其是团队开发,尽可能的避免全局变量

  1. 使用命名空间即只定义一个变量空间(如 JQuery -> $)。但是当你引用多个 js 文件时,恰巧这些文件都同时自定义了相同的变量符号。你就悲剧了。
  2. 使用匿名函数
(function(){})();

可能会造成内存消耗多大,甚至内存泄漏等情况

因此,尽可能的不要使用全局变量,如果不得不使用,请使用全部的大写字母进行命名。如:

MAX_SIZE // 推荐

推荐指数:????????????????

松耦合

将 js 和 css 进行抽离

松耦合:当你能够修改一个组件而不需要更改其他的组件。松耦合对于代码维护性至关重要,因为你绝对不希望开发人员在修改代码时,破坏或者改动其他的代码

/*
  好的做法
*/
var el = document.getElementById('div1');
el.classList.add('blue')
document.body.appendChild(el)
    
/*
  不好的做法。没有将 css 和 js 进行解藕
*/
var el = document.getElementById('div2');
el.style.width = '200px';
el.style.height = '200px'
el.style.background = 'blue';
document.body.appendChild(el)

推荐指数:????????????

将 html 和 js 进行抽离

/*
  不好的做法。没有实现 html 和 js 解藕
*/
var ul = document.createElement('ul');
ul.innerHTML = `
    <li>li</li>
    <li>li</li>
    <li>li</li>
`
document.body.appendChild(ul)

推荐指数:????????????

配置数据

对于应用中写死的值,可能会频繁的更改。因此,将配置数据从代码中抽离,保存在 config 对象中,这样对配置数据的修改可以完全和使用这些数据的代码隔离开来

URL = 'http://xxxxx/index.html?xxx=123

推荐指数:????????????????

组件化和模块化

标准的模块应该是“分工明细,职责单一,不牵扯需求逻辑”。就像是钉子,哪里需要往哪里按。使用模块化和组件化避免了造轮子的重复性工作,且降低了耦合,避免了逻辑错误,使你的代码产生质的飞跃

参考资料

  1. 编写可维护的 javascript
  2. 阮一峰的网络日志
退出移动版