前端团队有评审代码的要求,但由于每个开发人员的水平不同,技术关注点不同,所以对代码评审的关注点不同,为了保证代码质量,团队代码风格统一,特此拟定一份《前端团队代码评审 CheckList 清单》,这样代码评审人员在评审代码时,可以参照这份清单,对代码进行评审。从而辅助整个团队提高代码质量、统一代码规范。
image.png

一、代码静态检查工具

1.1、使用 eslint 工具对 javascript 代码进行检查

eslint 检查的规范继承自 eslint-config-standard 检验规则,具体的规则介绍参照链接:cn.eslint.org/docs/rules/ ,这里及以下部分不再重复介绍这些检验规则。

1.2、使用 stylelint 工具对 css 样式代码进行检查

stylelint 检查的规范继承自 stylelint-config-standard 检验规则,具体的规则介绍参照链接:www.npmjs.com/package/sty… ,这里及以下部分不再重复介绍这些检验规则。

二、命名规范

2.1、JS 采用 Camel Case 小驼峰式命名

推荐:

studentInfot

2.2、避免名称冗余

推荐:

  1. const Car = {
  2. make: "Honda",
  3. model: "Accord",
  4. color: "Blue"
  5. };

不推荐:

  1. const Car = {};
  2. Car.carMake = "Honda",
  3. Car.carModel: "Accord",
  4. Car.carColor: "Blue"

2.3、CSS 类名采用 BEM 命名规范

推荐:

  1. .block__element{}
  2. .block--modifier{}

2.4、命名符合语义化

命名需要符合语义化,如果函数命名,可以采用加上动词前缀:
动词含义
can 判断是否可执行某个动作
has 判断是否含有某个值is 判断是否为某个值
get/fetch 获取某个值
set 设置某个值
on点击开始执行某个事件

推荐:

  1. //是否可阅读
  2. function canRead(){
  3. return true;
  4. }
  5. //获取姓名
  6. function getName{
  7. return this.name
  8. }

三、JS 推荐写法

3.1、每个常量都需命名

每个常量应该命名,不然看代码的人不知道这个常量表示什么意思。

推荐:

  1. const COL_NUM = 10;
  2. let row = Math.ceil(num/COL_NUM);

不推荐:

  1. let row = Math.ceil(num/10);

3.2、推荐使用字面量

创建对象和数组推荐使用字面量,因为这不仅是性能最优也有助于节省代码量。

推荐:

  1. let obj = {
  2. name:'tom',
  3. age:15,
  4. sex:'男'
  5. }

不推荐:

  1. let obj = {};
  2. obj.name = 'tom';
  3. obj.age = 15;
  4. obj.sex = '男';

3.3、对象设置默认属性的推荐写法

推荐:

  1. const menuConfig = {
  2. title: "Order",
  3. // User did not include 'body' key
  4. buttonText: "Send",
  5. cancellable: true
  6. };
  7. function createMenu(config) {
  8. config = Object.assign(
  9. {
  10. title: "Foo",
  11. body: "Bar",
  12. buttonText: "Baz",
  13. cancellable: true
  14. },
  15. config
  16. );
  17. // config now equals: {title: "Order", body: "Bar", buttonText: "Send", cancellable: true}
  18. // ...
  19. }
  20. createMenu(menuConfig);

不推荐:

  1. const menuConfig = {
  2. title: null,
  3. body: "Bar",
  4. buttonText: null,
  5. cancellable: true
  6. };
  7. function createMenu(config) {
  8. config.title = config.title || "Foo";
  9. config.body = config.body || "Bar";
  10. config.buttonText = config.buttonText || "Baz";
  11. config.cancellable =
  12. config.cancellable !== undefined ? config.cancellable : true;
  13. }
  14. createMenu(menuConfig);

3.4、将对象的属性值保存为局部变量

对象成员嵌套越深,读取速度也就越慢。所以好的经验法则是:如果在函数中需要多次读取一个对象属性,最佳做法是将该属性值保存在局部变量中,避免多次查找带来的性能开销。

推荐:

  1. let person = {
  2. info:{
  3. sex:'男'
  4. }
  5. }
  6. function getMaleSex(){
  7. let sex = person.info.sex;
  8. if(sex === '男'){
  9. console.log(sex)
  10. }
  11. }
  12. 不推荐:
  13. let person = {
  14. info:{
  15. sex:'男'
  16. }
  17. }
  18. function getMaleSex(){
  19. if(person.info.sex === '男'){
  20. console.log(person.info.sex)
  21. }
  22. }

3.5、字符串转为整型

当需要将浮点数转换成整型时,应该使用Math.floor()或者Math.round(),而不是使用parseInt()将字符串转换成数字。Math 是内部对象,所以Math.floor()其实并没有多少查询方法和调用时间,速度是最快的。

推荐:

  1. let num = Math.floor('1.6');

不推荐:

  1. let num = parseInt('1.6');

3.6、函数参数

函数参数越少越好,如果参数超过两个,要使用 ES6的解构语法,不用考虑参数的顺序。

推荐:

  1. function createMenu({ title, body, buttonText, cancellable }) {
  2. // ...
  3. }
  4. createMenu({
  5. title: 'Foo',
  6. body: 'Bar',
  7. buttonText: 'Baz',
  8. cancellable: true
  9. });

不推荐:

  1. function createMenu(title, body, buttonText, cancellable) {
  2. // ...
  3. }

3.7、使用参数默认值

使用参数默认值 替代 使用条件语句进行赋值。

推荐:

  1. function createMicrobrewery(name = "Hipster Brew Co.") {
  2. // ...
  3. }

不推荐:

  1. function createMicrobrewery(name) {
  2. const breweryName = name || "Hipster Brew Co.";
  3. // ...
  4. }

3.8、最小函数准则

这是一条在软件工程领域流传久远的规则。严格遵守这条规则会让你的代码可读性更好,也更容易重构。如果违反这个规则,那么代码会很难被测试或者重用 。

3.9、不要写全局方法

在 JavaScript 中,永远不要污染全局,会在生产环境中产生难以预料的 bug。举个例子,比如你在 Array.prototype 上新增一个 diff 方法来判断两个数组的不同。而你同事也打算做类似的事情,不过他的 diff 方法是用来判断两个数组首位元素的不同。很明显你们方法会产生冲突,遇到这类问题我们可以用 ES2015/ES6 的语法来对 Array 进行扩展。

推荐:

  1. class SuperArray extends Array {
  2. diff(comparisonArray) {
  3. const hash = new Set(comparisonArray);
  4. return this.filter(elem => !hash.has(elem));
  5. }
  6. }

不推荐:

  1. Array.prototype.diff = function diff(comparisonArray) {
  2. const hash = new Set(comparisonArray);
  3. return this.filter(elem => !hash.has(elem));
  4. };

3.10、推荐函数式编程

函数式变编程可以让代码的逻辑更清晰更优雅,方便测试。

推荐:

  1. const programmerOutput = [
  2. {
  3. name: 'Uncle Bobby',
  4. linesOfCode: 500
  5. }, {
  6. name: 'Suzie Q',
  7. linesOfCode: 1500
  8. }, {
  9. name: 'Jimmy Gosling',
  10. linesOfCode: 150
  11. }, {
  12. name: 'Gracie Hopper',
  13. linesOfCode: 1000
  14. }
  15. ];
  16. let totalOutput = programmerOutput
  17. .map(output => output.linesOfCode)
  18. .reduce((totalLines, lines) => totalLines + lines, 0)

不推荐:

  1. const programmerOutput = [
  2. {
  3. name: 'Uncle Bobby',
  4. linesOfCode: 500
  5. },
  6. {
  7. name: 'Suzie Q',
  8. linesOfCode: 1500
  9. }, {
  10. name: 'Jimmy Gosling',
  11. linesOfCode: 150
  12. }, {
  13. name: 'Gracie Hopper',
  14. linesOfCode: 1000
  15. }
  16. ];
  17. let totalOutput = 0;
  18. for (let i = 0; i < programmerOutput.length; i++) {
  19. totalOutput += programmerOutput[i].linesOfCode;
  20. }

3.11、使用多态替换条件语句

为了让代码更简洁易读,如果你的函数中出现了条件判断,那么说明你的函数不止干了一件事情,违反了函数单一原则 ;并且绝大数场景可以使用多态替代

推荐:

  1. class Airplane {
  2. // ...
  3. }
  4. // 波音777
  5. class Boeing777 extends Airplane {
  6. // ...
  7. getCruisingAltitude() {
  8. return this.getMaxAltitude() - this.getPassengerCount();
  9. }
  10. }
  11. // 空军一号
  12. class AirForceOne extends Airplane {
  13. // ...
  14. getCruisingAltitude() {
  15. return this.getMaxAltitude();
  16. }
  17. }
  18. // 赛纳斯飞机
  19. class Cessna extends Airplane {
  20. // ...
  21. getCruisingAltitude() {
  22. return this.getMaxAltitude() - this.getFuelExpenditure();
  23. }
  24. }

不推荐:

  1. class Airplane {
  2. // ...
  3. // 获取巡航高度
  4. getCruisingAltitude() {
  5. switch (this.type) {
  6. case '777':
  7. return this.getMaxAltitude() - this.getPassengerCount();
  8. case 'Air Force One':
  9. return this.getMaxAltitude();
  10. case 'Cessna':
  11. return this.getMaxAltitude() - this.getFuelExpenditure();
  12. }
  13. }
  14. }

3.12、定时器是否清除

代码中使用了定时器 setTimeout 和 setInterval,需要在不使用时进行清除。暂无规定,待补充

四、团队其它规范

4.1、尽量不手动操作 DOM

因为团队现在使用 vue 框架,所以在项目开发中尽量使用 vue 的特性去满足我们的需求,尽量(不到万不得已)不要手动操作DOM,包括:增删改dom元素、以及更改样式、添加事件等。

4.2、删除弃用代码

很多时候有些代码已经没有用了,但是没有及时去删除,这样导致代码里面包括很多注释的代码块,好的习惯是提交代码前记得删除已经确认弃用的代码,例如:一些调试的console语句、无用的弃用代码。

4.3、保持必要的注释

代码注释不是越多越好,保持必要的业务逻辑注释,至于函数的用途、代码逻辑等,要通过语义化的命令、简单明了的代码逻辑,来让阅读代码的人快速看懂。