1 前言
虽然本文档是针对JavaScript设计的,但是在使用各种JavaScript的预编译语言时(如TypeScript等)时,适用的部分也应遵循本文档的约定。
2 代码风格
2.1 代码格式化
- 代码统一使用prettier进行格式化处理
- prettier安装,各项目可固定使用某一版本。
1 2 3
| yarn add prettier@1.14.3 --dev --exact
npm install --save-dev --save-exact prettier@1.14.3
|
prettier在IDE上的配置
每次提交PR时,commiter需对代码格式化,否则reviewer将拒绝合并。
2.2 命名
文件、类、接口、函数或变量等命名,使用大驼峰、小驼峰或全大写,不推荐使用下划线作为命名首字母
2.2.1 文件
一个文件对应一组逻辑(一个类、一些功能函数的集合、样式集合)
2.2.1.1 文件内部是一个类的,使用大驼峰命名。
2.2.1.2 文件内部是一些功能函数集合的,使用小驼峰命名。
2.2.1.3 文件内部是样式集合的,使用小驼峰命名。
2.2.2 类、接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class HomeScreen {
title: string; eventFunc = (event: type): returnType => { }; calculate(input: type): returnType { } }
interface User { name: string; login: (input: type) => returnType; }
|
2.2.3 函数名,使用小驼峰命名。
1 2 3
| function funcName(input: type): returnType { }
|
2.2.4 全局常量名,使用全大写,并用下划线连接单词。
1
| const SCREEN_WIDTH = 375;
|
2.2.5 全局变量(不推荐使用,一定要使用请勿导出),使用大驼峰命名。
2.2.6 变量名,使用小驼峰命名。
2.2.7 枚举类型命名
1 2 3 4 5 6
| enum LoanState {
REPAYMENT = 1, }
|
2.2.8 其他命名规范
2.2.8.1
由多个单词组成的缩写词,在命名中,根据当前命名法和出现的位置,所有字母的大小写与首字母的大小写保持一致。
1 2 3 4 5 6 7
| function XMLParser(input: type): returnType { }
function insertHTML(element: type, html: type): returnType { }
let httpRequest = new HTTPRequest();
|
2.2.8.2
类名、接口、枚举使用名词
1 2 3 4 5 6 7 8 9 10 11
| class HomeScreen { }
interface Personal { }
enum LoanState { }
|
2.2.8.3
函数名使用动宾短语
1 2 3 4 5 6 7
| function setState(state: type): returnType { }
function calculateHeight(height: type): returnType { }
|
2.2.8.4
boolean
类型的变量使用is
或has
开头,返回值为boolean
类型的函数也遵循此规则
1 2 3 4 5 6 7
| let isReady = false; let hasMore = false;
function isSthTodo(): boolean { ... return true; }
|
2.3 类型声明和使用
- 所有类或接口的成员,变量、函数(参数、返回值)的声明,都必须声明类型,且不允许使用
any
。能隐式推导出类型的,可不声明类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| let height: number;
interface User { name: string; age: number; }
const PI = 3.1415926;
let user: User = { name: "fmb", age: 12 }
function setName(name: string): void { }
let height;
user = { name: "xx", age: 1; }
interface User { name: any; age: any; }
|
- 推荐使用
undefined
作为类型声明,而非null
。
1 2 3 4 5 6 7 8 9 10 11
| interface User { name: string; arg: number | undefined; }
interface User { name: string; arg: number | null; }
|
2.4 注释
2.4.1 文件
创建文件时,开发者需创建一个文件头注释,如下:
2.4.2 类、接口或枚举
创建类、接口或枚举时,开发者需创建一个类头注释,如下:
1 2 3 4 5 6
|
interface User { }
|
2.4.3 函数
创建函数时,开发者需创建一个函数头注释,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
function foo(p1: type1, p2: type2, p3?: type3): returnType { let p3 = p3 || 10; return { p1: p1, p2: p2, p3: p3 }; }
|
2.4.4 其他注释
推荐使用/* */
进行细节注释,不推荐使用//
进行细节注释。
1 2 3
| const PI = 3.14;
const FML = "f**k my life";
|
2.5 语言特性
2.5.1 变量
- 使用
let
定义变量而不是var
- 每个
let
声明一个变量。
1 2 3 4
| let a = 1;
let a = 2, b = 1; var a = 3;
|
2.5.2 条件
- 除
null
或undefined
的判断可用==
外,其余的条件判断都使用===
,以避免隐式的类型转换。
- 尽可能的使用简洁的条件表达式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| if (age === 10) if (arg == 10)
let name = "abc";
if (!name) if (name === "")
let isLogin = true; if (!isLogin) if (isLogin == false)
let array: number[];
if (array.length) if (array.length > 0)
if (noValue == null) if (noValue == undefined) if (hasValue)
if (novalue === null) if (novalue === undefined) if (hasvalue !== undefined)
|
2.5.3 循环
1 2 3
| for (statement1; statement2; statement3) for (... in ...) array.forEach(...)
|
2.5.4 类型
2.5.4.1 类型检测
类型检测优先使用 typeof
。对象类型检测使用 instanceof
。null
或undefined
的检测使用 == null
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| typeof variable === 'string'
typeof variable === 'number'
typeof variable === 'boolean'
typeof variable === 'function'
typeof variable === 'object'
variable instanceof RegExp
variable instanceof Array
variable == null
|
2.5.4.2 类型转换
[建议] 转换成 string 时,使用"" +
或String(sth)
。
1 2 3 4 5
| let str = "" + sth; let str = String(sth);
let str = new String(sth); let str = sth.toString();
|
[建议] 转换成 number 时,通常使用 +str 或 Number(str)
,若要转换的字符串结尾包含非数字并期望忽略时,使用 parseInt
(必须指定进制)或parseFloat
。
1 2 3 4 5 6 7 8 9
| let num = +str; let num = Number(str);
str = "123.4hello"; let num = ParseInt(str, 10); let num = ParseFloat(str);
let num = new Number(str)
|
[建议] 转换成 boolean 时,使用 !!
。
1 2
| let num = 3.14; let condition = !!num;
|
[建议] number 去除小数点,使用 Math.floor / Math.round / Math.ceil,不使用 parseInt。
1 2 3 4 5 6 7
| let num = 3.14; Math.ceil(num);
let num = 3.14; parseInt(num, 10);
|
3 实用库介绍
用于创建、格式化number类型,以及一些number处理的实用方法。
1 2 3
| let num = numeral(1000000); let value = num.value(); value = num.format('0,0.00')
|
更多详细用法详见官方文档
用于创建、格式化时间,以及一些时间处理的实用方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const timestamp = 1539571685044; const date = new Date(timestamp); const dateStr = "1989-06-04 11:11:11"
moment(timestamp).format("YYYY.MM.DD HH:mm:ss");
moment(date).format("YYYY年MM月DD日 HH:mm:ss")
moment(dateStr, "YYYY-MM-DD HH:mm:ss").format("YYYY年MM月DD日 HH:mm:ss")
...
|
更多详细用法详见官方文档