前言
好的编码习惯,能够提升个人技术素养,产品质量,减少bug数量,易维护,易迭代,多人协作易沟通交接等多个好处。今天从个人角度谈谈自己的一些编码习惯,以及为什么要这么做。
这并不是什么技术标准,不同的人有不同的看法和喜好。 但我们要牢记一条:优秀的代码一定是可读性非常高的代码。
基础篇
主要从javascript
代码的基础编写的角度阐述。
===
与==
在遇到基本数据类型判断的情况下,强制使用全等于判断===
。因为js是是弱类型语言,非全等判断==
会存在隐式类型转换的问题,在一个复杂的业务场景中,如果导出充斥着非全等判断,那么开发者可能会无法第一时间明确业务中过的数据类型及结构,对后来的协作开发人员也非常不友好。而在其他大部分编程语言中,包括近年火热的Typescript
本身也是有解决这一问题。 所以在我们开发中遇到当前场景,务必使用全等判断,如果数据类型不明确,我们也要通过其他方法转换成明确的类型再继续判断。
1
2
3
4
let a = '0'
console.log(a == false)
console.log(Number(a) == false)
console.log(Number(a) === false)
数据类型转换
数据类型转换分为强制转换和隐形转换。在大多数场景建议使用强制转换。转换字符串使用String
,数字使用Number
, 因为隐式转换的写法具有一定的迷惑性,大量的隐式转换放在一起会大大降低代码的可读性,某些场景下会使代码变得不稳定,增加bug排查难度,所以尽量避免书写隐式转换类型的代码。
1
2
console.log(+'1' + '1' + +'1' )
console.log(+'1' + +'1' +'1')
不要使用过时的Javscript技巧
了解ES高版本语法,如果可以,尽可能面使用新语法开发,因为高阶语法在底层实现上性能通常会优于旧版本。 一个经典的例子是搜索一个数组是否包含一个元素。 使用 array.indexOf(item) !== -1
来监测元素是否存在。 ECMAScript 2015及更高版本的功能变得越来越强大。 你可以使用新的语言特性安全地重构很多hacks。 使用ES2015方法 array.includes(item)
重构array.indexOf(item) !== -1
。
1
2
3
4
5
6
7
8
const arr = [1,2,3,4,5,6,7,8,9]
// 查找数组arr中是否有 number 5
console.log(arr.indexOf(5) !== -1) // bad
console.log(arr.includes(5)) //good
// 查找数组中所有大于数字6的元素
// 判断数组中所有的元素是否大于数字3
// 数组中所有元素的累加和是多少
不要污染函数作用域
在ES6之前,通常会在顶级作用域或函数作用域顶级声明所有变量,但其实一些变量只在某一块作用域生效,所以会造成作用域污染,所以我们要尽可能的控制每一个变量的生命周期。比如ES6开始引入的块级作用域的概念,可以很方便的解决这个问题。
1
2
3
4
5
6
7
8
9
10
11
12
// 错误的
let message;
if (notFound) {
message = 'xxxxxx'
// 使用 message...
}
// 正确的
if (notFound) {
const message = 'xxxxxx'
// 使用 message...
}
避免使用null
作为函数入参
避免使函数的入参为null
, 一旦null
出现在调用堆栈中,就需要在每一个可能访问的函数检查中,来判断是否为null
函数导出
全局公共函数导出文件,不推荐export
一个对象的方式,而是export
一个个函数的形式。这样可以实现按需导入.
1
2
3
4
5
6
7
8
9
10
// bad
util.fun = function() {};
export default util;
// bad
export default {
fun
}
// good
export function fun() {};
import {fun} from '';
了解高阶函数,在正确场景使用正确的函数
1
2
3
4
5
6
// 如果只是遍历
const arr = [1, 2, 3];
// bad
arr.map(item => {});
// good
arr.forEach(item => {});
如果数据量特别大,尤其是遍历操作,推荐使用普通for循环,因为高阶函数的底层也是封装的for循环
1
2
3
const arr = [];
// beat
for (let i = 0, len = arr.length; i < len; i++) {}
链式调用使用 缩进和.
强调调用而非新语句
1
2
3
4
5
6
7
8
9
// bad
$('#items').find('.selected').highlight().end().find('.open').updateCount()
// good
$('#items')
.find('.selected')
.highlight()
.end()
.find('.open')
.updateCount()
删除无用的大篇幅代码注释
删除没有必要的声明
1
2
3
4
5
6
7
8
9
10
11
12
13
// bad
let dataList = []
dataList.push(row)
let data = {
code: this.code,
list: dataList
}
// good
let data = {
code: this.code,
list: [ row ]
}
事件处理
注重隔离应用逻辑和用户行为,专注一个函数只做一件事,便于函数复用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// bad
function handClick (event) {
const popup = document.getElementById("popup")
popup.style.left = event.clientX
popup.style.top = event.clientY
popup.className = "show"
}
// good
function showPopup(event){
const popup = document.getElementById("popup")
popup.style.left = event.clientX
popup.style.top = event.clientY
popup.className = "show"
}
function handClick (event) {
showPopup(event)
}
适当抛出自定义错误
当业务变得复杂,需求变得庞大,适当的抛出自定义错误, 有助于调试,及加深业务理解。
1
throw new Error('函数名:可能得原因')
不要使用随意的编码风格(不要破坏项目的编码风格)
开始一个新项目首先要确定整体代码风格,可以参考已有的代码风格,配合eslint配置验证。接手一个项目,在开始编码前,确认当前项目的代码风格并严格遵守。 有什么比阅读具有随机编码风格的代码更令人生畏的呢? 你永远不知道会发生什么! 如果代码库包含许多开发人员的不同编码风格怎么办? 各式各样的人物涂鸦墙。
组件封装要确保组件代码可读性
公共组件是团队协作的基础,可读性就显得尤为总要,怎么增加组件的可读性呢?首先组件命名要语义化,大家看到组件就一目了然,知道该组件的功能是啥;其次我们组件要有一个清晰明了的注释,演示组件用例,属性、参数、方法说明,让大家几乎不用动脑就可以完美使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* 表格筛选器组件
*
* 使用说明:
* 1,导入组件:import TableFilter from "~/components/sizer/TableFilter.vue"
* 2,注册组件:components: {TableFilter}
* 3,渲染:<TableFilter :listSizer="listSizer" :listPrmt="listPrmt" @ichub="search"></TableFilter>
*
* 属性说明:
* :listSizer:Array 过滤器基本配置项
* :listPrmt:Object 过滤参数对象
* @ichub: function 点击ichub按钮过滤事件--参数:Object 当前过滤参数对象
*
* 数据说明:
* listSizer: [{ /过滤器基本配置项数据
* type: "text", //输入框类型:text普通输入框,select下拉输入框,date时间选择输入框
* placeholder: "型号", //输入框提示
* name: "sku_name", //绑定的字段名与listPrmt里面的键对应
* key: "f_sku_name", //循环唯一标识key
* width: "g-width-15" //输入框站筛选器的宽度(百分比)
* }]
** /
组件要注重逻辑功能和理性
封装公共组件要设计好组件功能,看哪些功能需要在组件内完成,哪些功能需要暴露给父组件。我们一般的设计原则是,能在组件内完成的功能,尽量不要暴露给父组件处理。
组件数据设计注重合理性
哪些数据需要父组件传进组件,哪些数据是组件自身拥有,哪些数据要输出给父组件一定要条理清晰。设计原则:组件自身除了必要的数据,一般不携带大量私有数据,尽量由父组件输入,处理完后根据业务场景决定是否需要输出。
组件注重扩展性
我们封装公共组件基本可以满足我们百分之80到90的业务场景,但是一些个性化话的场景,需要组件的大部分功能,但是又有新的需求,这时候再开发一个新的组件没有必要,那么我们就要在原有组件的基础上加功能。这是时候我们就要用到插槽slot来做好预留,来增强组件的扩展性。
代码文件适当拆分
- 代码篇幅过大时,解偶归类部分方法,迁移到另一个文件,再
import
进来使用 - 定义顶级常量数据, 可考虑迁移到单独的文件中管理。