尽管技术一般,但是也要写一手好代码让人看起来有大神风范;好代码不仅要精炼,更要易读。
一、变量(努力做一个干净的小变量好嘛)
(1)变量的数量控制
避免滥用变量:数据只使用一次或不使用就无需装到变量中,例
let temp = 2; // 定义好了之后就没有用过
function func() {
var a = 1;
var b = 2;
var c = a + b;
var d = c + 1;
var e = d + a;
return e;
}
// 修改为以下代码更合理
function func() {
var a = 1;
var b = 2;
return 2*a + b + 1;
}
(2)变量命名
拒绝那些自我感觉良好的缩写或是中文的拼音,不知道怎么翻译请动动小手指去谷歌翻译一下。其实并不需要对每个变量进行注释,直接写明了的变量名更佳。
// 错误示范
let fName = 'ben'; // 过度缩写,让人不明所以
let lName = 'cooper';
let aihao = 'sing'; // 使用中文拼音
let nameString; // 命名过于啰嗦
// 这样写更佳
let firstName = 'ben';
let lastName = 'cooper';
let hobby = 'sing';
let name;
(3)特定的变量
将无说明的参数添加到变量中,让后来者一目了然
// 拒绝无说明的参数
if(item.length <= 10) { // 不懂为啥不能超过10,10是什么玩意?
....
}
// 添加变量,让10有归属感
const MAX_NAME_LENGTH = 10;
if(item.length <= MAX_NAME_LENGTH) { // 10的归属感来了
....
}
(4)尽量少定义全局变量
忌在不同的文件定义全局变量,是在需要全局共享变量,可以使用vuex,redux或是自己写服务
// one.js
window.name = 'one';
// two.js
window.name = 'two';
// three.js
window.name = 'three'; // 三个文件的加载顺序不同,会使得window.name的值不同,同时,你对window.name做的操作又有可能不生效
(5)变量赋值
赋值求值变量时,需要做好默认值赋值
const MAX_NAME_LENGTH = 10;
let lastName = fullName[1] || ''; // fullName[1]取不到时也不至于lastName的赋值为undefined
if(lastName < MAX_NAME_LENGTH) {
....
}
let pptValue = Object.attr || 0; // 因为Object.attr有可能为空,所以要默认值
二、函数(一个萝卜一个坑,一个函数一个功能)
(1)函数的命名
最好能从函数名可以看出函数的返回值类型,对于返回布尔值的函数,最好以should/is/can/has开头,动作函数要以动词开头
function showOrdersList() { ... }
// 明确返回值类型
function shouldShowDialog() { ... }
function isEmpty() { ... }
function canAddItem() { ... }
function hasCard() { ... }
// 动作函数以动词开头
function sendMessage() { ... }
function submitForm() { ... }
(2)功能函数最好是纯函数
不要让功能函数的输出变化无常,我们希望的是,功能函数的输入一致时,输出结果永远是唯一的。
function plusAbc(a, b, c) {
var c = fetch('../api');
return a + b + c;
} // 该函数的输出变化无常,api的返回值变化,同样的输入也有不同的输出值
function plusAbc(a, b, c) {
return a + b + c;
} // 同样的输入值a,b,c,函数返回的结果永远相同
(3)函数传参
传参时最好有说明,避免不必要的麻烦
getOrdersList(true,10,1); // true,10,1是啥意思,看不懂看不懂
getOrdersList({
showPage: true,
limit: 10,
page: 1
}); // 原来这三个值是用来设置分页显示的
(4)一个函数只做一件事
这是判断代码好坏的一个很重要的点,代码的低耦合性可以提高代码的性能,让代码更容易编写,理解,重组,复用和测试。
(5)优先使用命令式编程
for(i=0; i < a.length; i++) {
a[i]++;
}
// 使用命令式编程;现在几乎所有的for循环都可以被map,filter,find,some,any,forEach等命令式编程锁取代
let b = a.map(item => ++item);
(6)函数中不要过多采用if else
可以使用switch或数据来代替过多的if else
if(a === 1) {
....
}else if(a === 2) {
....
}else if(a === 3) {
...
}else {
....
}
// 使用switch代替
switch(a) {
case 1:
....
case 2:
....
case 3:
....
default:
....
}
// 使用数组代替
let handler = {
1: () => { .... },
2: () => { .... },
3: () => { .... },
default: () => { .... },
}
handler[a]()
三、尽量使用ES6、ES7的新语法
(1)尽量使用箭头函数()=>{}
function foo() {
....
}
//使用箭头函数
let foo = () => {
....
}
(2)尽量采用模板字符连接字符串
console.log('name:' + name);
// 使用模板字符
console.log(`name:${name}`);
(3)使用解构赋值
//传统的赋值方法
var userData = {
name: 'Lily',
age: 23
};
var name = userData.name;
var age = userData.age;
var userList = ['Lily', 'Bob'];
var firstPerson = userList[0];
var lastPerson = userList[1];
// 使用解构赋值
const userData = {
name: 'Lily',
age: 23
};
const {name, age} = userData;
const userList = ['Lily', 'Bob'];
const [firstPerson, lastPerson] = userList;
(4)尽量使用类class
// 采用ES6类实现继承
class People {
constructor(name) = {
this.name = name;
}
walk() {
....
}
}
class Men extends People {
constructor(name, age) = {
super(name)
this.age = age
}
drive() {
....
}
}
class Women extends People {
constructor(name, hobby) = {
super(name)
this.hobby = hobby
}
speak() {
....
}
}