前端代码编写注意事项

| 字数 778
  1. 1. 变量
  2. 2. 函数
  1. 1. 变量
  2. 2. 函数

变量

  1. 声明不用,数据只使用一次或不使用就无需装到变量中

  2. 变量命名,驼峰、简洁、易懂

  3. 特定变量:

    1
    2
    3
    4
    5
    const MAX_INPUT_LENGTH = 8;
    if (value.length < MAX_INPUT_LENGTH) {
    // 一目了然,不能超过最大输入长度
    ....
    }
  4. 使用说明性的变量(即有意义的变量名)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const address = 'One Infinite Loop, Cupertino 95014';

const cityZipCodeRegex = /^[^,\]+[,\s]+(.+?)s*(d{5})?$/;

saveCityZipCode(
address.match(cityZipCodeRegex)[1],// 这个公式到底要干嘛,对不起,原作者已经离职了。自己看代码
address.match(cityZipCodeRegex)[2], // 这个公式到底要干嘛,对不起,原作者已经离职了。自己看代码
);

// 改为如下:

const address = 'One Infinite Loop, Cupertino 95014';

const cityZipCodeRegex = /^[^,\]+[,\s]+(.+?)s*(d{5})?$/;

const [, city, zipCode] = address.match(cityZipCodeRegex) || [];

saveCityZipCode(city, zipCode);
  1. 避免使用太多的全局变量,如有需要请使用命名空间

  2. 对于求值变量做好默认值(兜底),对于赋值变量可不用:

    1
    2
    3
    4
    5
    6
    //其实在项目中有很多求值变量,对于每个求值变量都需要做好兜底。
    let propertyValue = Object.attr || 0; // 因为Object.attr有可能为空,所以需要兜底。

    // 但是,赋值变量就不需要兜底了。
    let a = 2; // 因为有底了,所以不要兜着。
    let myName = 'Tiny'; // 因为有底了,所以不要兜着。

函数

1.对于返回true or false的函数,最好以should/is/can/has开头

2.动作函数已动词开头否则不好辨别意图

3.功能函数最好为纯函数:

1
2
3
4
5
6
7
8
9
10
// NO: 不要让功能函数的输出变化无常。
function plusAbc(a, b, c) { // 这个函数的输出将变化无常,因为api返回的值一旦改变,同样输入函数的a,b,c的值,但函数返回的结果却不一定相同。
var c = fetch('../api');
return a+b+c;
}

//YES:功能函数使用纯函数,输入一致,输出结果永远唯一
function plusAbc(a, b, c) { // 同样输入函数的a,b,c的值,但函数返回的结果永远相同。
return a+b+c;
}

  1. 函数传参要有说明(参数过多,使用对象来代替)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    // NO:传参无说明
    page.getSVG(api, true, false); // true和false啥意思,一目不了然

    // YES: 传参有说明
    page.getSVG({
    imageApi: api,
    includePageBackground: true, // 一目了然,知道这些true和false是啥意思
    compress: false,
    })
  2. 一个函数完成一个独立的功能,不要一个函数混杂多个功能

  3. 优先使用函数式编程,少用for

  4. 多重判断使用array.includes(逻辑复杂可以考虑使用策略模式) :

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // NO 
    function test(fruit)
    if (fruit == 'apple' || fruit == 'strawberry') {
    console.log('red');
    }
    }

    // YES
    function test(fruit) {
    const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries'];

    if (redFruits.includes(fruit)) {
    console.log('red');
    }
    }
  5. 更少的嵌套,尽早return,考虑使用非(!)

  6. 倾向于遍历对象还不是switch:

    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
    // NO
    function test(color) {
    // 使用条件语句来寻找对应颜色的水果
    switch (color) {
    case 'red':
    return ['apple', 'strawberry'];
    case 'yellow':
    return ['banana', 'pineapple'];
    case 'purple':
    return ['grape', 'plum'];
    default:
    return [];
    }
    }

    // test results
    test(null); // []
    test('yellow'); // ['banana', 'pineapple']

    // YES
    const fruitColor = {
    red: ['apple', 'strawberry'],
    yellow: ['banana', 'pineapple'],
    purple: ['grape', 'plum']
    };

    function test(color) {
    return fruitColor[color] || [];
    }
  7. 对 所有/部分 判断使用 Array.every & Array.some