代码命名技巧
在编写 JavaScript / TypeScript 时,为变量和函数的命名也是新手开发者容易花费比较多时间的一件事情,笔者也分享自己常用的命名套路,可以大幅度降低命名的思考时间,而且可以体现一定的语义化。
变量的命名
首先笔者遵循变量只使用 camelCase 小驼峰风格的基本原则,并且根据不同的类型,搭配不同的命名前缀或后缀。
对于 string
字符串类型,使用相关的名词命名即可。
import { ref } from 'vue'
// 用户名
const username = ref<string>('Petter')
// 职业
const profession = ref<string>('Front-end Engineer')
对于 number
数值类型,除了一些本身可以代表数字的名词,例如年龄 age
、秒数 seconds
,其他的情况可以搭配后缀命名,常用的后缀有 Count
、 Number
、 Size
、 Amount
等和单位有关的名词。
import { ref } from 'vue'
// 最大数量
const maxCount = ref<number>(100)
// 页码
const pageNumber = ref<number>(1)
// 每页条数
const pageSize = ref<number>(10)
// 折扣金额
const discountAmount = ref<number>(50)
对于 boolean
布尔值类型,可搭配 is
、 has
等 Be 动词或判断类的动词作为前缀命名,并视情况搭配行为动词和目标名词,或者直接使用一些状态形容词。
import { ref } from 'vue'
// 是否显示弹窗
const isShowDialog = ref<boolean>(false)
// 用户是否为 VIP 会员
const isVIP = ref<boolean>(true)
// 用户是否有头像
const hasAvatar = ref<boolean>(true)
// 是否被禁用
const disabled = ref<boolean>(true)
// 是否可见
const visible = ref<boolean>(true)
之所以要搭配 is
开头,是为了和函数区分,例如 showDialog()
是显示弹窗的方法,而 isShowDialog
才是一个布尔值用于逻辑判断。
对于数组,通常使用名词的复数形式,或者名词加上 List
结尾作为命名,数组通常会有原始数据类型的数组,也有 JSON 对象数组,笔者习惯对前者使用名词复数,对后者使用 List
结尾。
import { ref } from 'vue'
// 每个 Item 都是字符串
const tags = ref<string>(['食物', '粤菜', '卤水'])
// 每个 Item 都是数值
const tagIds = ref<number>([1, 2, 3])
// 每个 Item 都是 JSON 对象
const memberList = ref<Member[]>([
{
id: 1,
name: 'Petter',
},
{
id: 2,
name: 'Marry',
},
])
如果是作为函数的入参,通常也遵循变量的命名规则。
除非是一些代码量很少的操作,可以使用 i
、 j
等单个字母的变量名,例如提交接口参数时,经常只需要提交一个 ID 数组,从 JSON 数组里提取 ID 数组时就可以使用这种简短命名。
// `map` 的参数命名就可以使用 `i` 这种简短命名
const ids = dataList.map(i => i.id)
函数的命名
函数的命名也是只使用 camelCase 小驼峰风格,通常根据该函数是同步操作还是异步操作,使用不同的动词前缀。
获取数据的函数,通常使用 get
、 query
、 read
等代表会返回数据的动词作为前缀,如果还是觉得很难确定使用哪一个,可以统一使用 get
,也可以根据函数的操作性质来决定:
- 如果是同步操作,不涉及接口请求,使用
get
作为前缀 - 如果是需要从 API 接口查询数据的异步操作,使用
query
作为前缀 - 如果是 Node.js 程序这种需要进行文件内容读取的场景,就使用
read
// 从本地存储读取数据
// 因为是同步操作,所以使用 `get` 前缀
function getLoginInfo() {
try {
const info = localStorage.getItem('loginInfo')
return info ? JSON.parse(info) : null
}
catch (e) {
return null
}
}
// 从接口查询数据
// 因为是异步操作,需要去数据库查数据,所以使用 `query` 前缀
async function queryMemberInfo(id: number) {
try {
const res = await fetch(`https://example.com/api/member/${id}`)
const json = await res.json()
return json
}
catch (e) {
return null
}
}
修改数据的函数,通常使用 save
、 update
、 delete
等会变更数据的动词作为前缀,一般情况下:
- 数据存储可以统一使用
save
- 如果要区分新建或者更新操作,可以对新建操作使用
create
,对更新操作使用update
- 删除使用
delete
或remove
- 如果是 Node.js 程序需要对文件写入内容,使用
write
- 表单验证合法性等场景,可以使用
verify
或check
- 切换可见性可以用
show
和hide
,如果是写在一个函数里,可以使用toggle
- 发送验证码、发送邮件等等可以使用
send
- 打开路由、打开外部 URL 可以使用
open
当然以上只是一些常用到的命名技巧建议,对于简单的业务,例如一个 H5 活动页面,也可以在同步操作时使用 set
表示可以直接设置,在异步操作时使用 save
表示需要提交保存。
// 将数据保存至本地存储
// 因为是同步操作,所以使用 `set` 前缀
function setLoginInfo(info: LoginInfo) {
try {
localStorage.setItem('loginInfo', JSON.stringify(info))
return true
}
catch (e) {
return false
}
}
// 将数据通过接口保存到数据库
// 因为是异步操作,所以使用 `save` 前缀
async function saveMemberInfo(id: number, data: MemberDTO) {
try {
const res = await fetch(`https://example.com/api/member/${id}`, {
method: 'POST',
body: JSON.stringify(data),
})
const json = await res.json()
return json.code === 200
}
catch (e) {
return false
}
}
Class 类上的方法和函数命名规则一样,但 Class 本身使用 PascalCase 命名法,代表这是一个类,在调用的时候需要 new
。
// 类使用 PascalCase 命名法
class Hello {
name: string
constructor(name: string) {
this.name = name
}
say() {
console.log(`Hello ${this.name}`)
}
}
const hello = new Hello('World')
hello.say() // Hello World