代码风格

基本规范可参考:JavaScript Standard Style

变量命名

【强制】 除了常量枚举变量使用Pascal命名法,其余情况统一使用Camel命名法

var loadingModules = {};

// 常量
var HTML_ENTITY = {};

// 类
class DemoClass{
}

【强制】常量全部使用大写字母,单词间用下划线_分隔

// 常量
var HTML_ENTITY = {};

强制】枚举变量采用Pascal命名法

var TargetState = {
    READING: 1,
    READED: 2,
    APPLIED: 3,
    READY: 4
};

【建议】Boolean类型的变量使用is或者has开头

let isLoading=true;
let hasMore=false;

注释

文档注释

使用/**...*/,需包含以下内容:
1、文档用途;
2、作者;
3、时间

/**
 @description 该文档用途
 @author abc
 @date 2020-02-04
*/

单行注释

【强制】必须独占一行,// 后跟一个空格

//这里是注释

多行注释

【建议】使用/** */

命名空间注释

【建议】使用@namespace表示

/**
 * @namespace
*/
var util = {};

类注释

【建议】使用@class表示类或构造函数

/**
* @class
*/
class DemoClass{

}

【建议】使用@extends 表示类的继承信息

/**
* @class 
* @extends DemoClass
*/
class ChildClass extends DemoClass{

}

函数或方法注释

【强制】如果有参数,必须包含参数信息说明
【强制】如果有返回值,必须包含返回值信息说明

@param + {参数数据类型} + 参数名称
@returns + {返回数据类型}

/**
 * @param {number} time
 * @param {string} option
 * @returns {string}
 */
function formatTime(time, option){
    //这里是代码
    return result;
}

事件注释

【强制】必须使用@event标识,事件参数及返回值同函数或方法注释

/**
 * @event
 * @param {string} value
 * @returns {string}
 */
function onChange(value){
    //这里是代码
    return result;
}

代码细节注释

【建议】对于内部实现,难以理解的代码需要对实现逻辑加以说明,注释方式可参考单行注释,必要时可换行

/**
 * @event
 * @param {string} value
 * @returns {string}
 */
function onChange(value){
    //这里是实现逻辑说明
    return result;
}

代码要求

1、【强制】变量使用前必须使用var或let定义;
解释:避免无意造成全局变量,污染环境。

// good
var name = 'MyName';

// bad
name = 'MyName';

2、【强制】每个var或者let只声明一个变量
解释:一个 var 声明多个变量,容易导致较长的行长度,并且在修改时容易造成逗号和分号的混淆。

//good
var name='myName';
var age=20;

//bad
var name='myName',
    age=20;

3、【强制】变量即用即声明,不要在函数或方法的开始位置统一声明所有变量
解释:变量声明与变量使用位置距离越远,阅读和维护成本越高,应尽量缩短变量声明与使用位置距离。

// good
function kv2List(source) {
    var list = [];
    for (var key in source) {
        if (source.hasOwnProperty(key)) {
            var item = {
                k: key,
                v: source[key]
            };
            list.push(item);
        }
    }
    return list;
}

// bad
function kv2List(source) {
    var list = [];
    var key;
    var item;
    for (key in source) {
        if (source.hasOwnProperty(key)) {
            item = {
                k: key,
                v: source[key]
            };
            list.push(item);
        }
    }
    return list;
}

4、条件判断
【强制】在等于判断中使用严格类型判断===,仅当null,undefined时候可使用==null
解释:使用===可避免判断中隐式类型转换。

// good
if (age === 30) {
    // ......
}

// bad
if (age == 30) {
    // ......
}

【建议】尽可能使用简式类型判断

// 字符串为空
// good
if (!name) {
    // ......
}

// bad
if (name === '') {
    // ......
}
// null 或 undefined

// good
if (noValue == null) {
  // ......
}

// bad
if (noValue === null || typeof noValue === 'undefined') {
  // ......
}

【建议】对于相同变量或表达式的多值条件,建议使用switch代替if else

// good
switch (typeof variable) {
    case 'object':
        // ......
        break;
    case 'number':
    case 'boolean':
    case 'string':
        // ......
        break;
}

// bad
var type = typeof variable;
if (type === 'object') {
    // ......
} 
else if (type === 'number' || type === 'boolean' || type === 'string') {
    // ......
}

【建议】如果函数中else后没有任何语句,可去掉else

// good
function getValue() {
    if (value) {
        return value;
    }

    return null;
}

// bad
function getValue() {
    if (value) {
        return value;
    }else {
        return null;
    }
}

5、循环
【建议】不要在循环体内包含函数表达式,应在循环外定义函数。
解释:循环体内会生成循环次数个函数定义。

// good
function clicker() {
    // ......
}

for (var i = 0, len = elements.length; i < len; i++) {
    var element = elements[i];
    addListener(element, 'click', clicker);
}

// bad
for (var i = 0, len = elements.length; i < len; i++) {
    var element = elements[i];
    addListener(element, 'click', function () {});
}

【建议】循环体内多次使用的不变值,应在循环外部使用变量缓存。

// good
var width = wrap.offsetWidth + 'px';
for (var i = 0, len = elements.length; i < len; i++) {
    var element = elements[i];
    element.style.width = width;
    // ......
}

// bad
for (var i = 0, len = elements.length; i < len; i++) {
    var element = elements[i];
    element.style.width = wrap.offsetWidth + 'px';
    // ......
}

【建议】对有序集合进行遍历时,建议缓存length。

for (var i = 0, len = elements.length; i < len; i++) {
    var element = elements[i];
    // ......
}

6、类型检测

【建议】建议优先使用typeof,对象使用instanceof,null或undefined可使用==null。

// string
typeof variable === 'string'

// number
typeof variable === 'number'

// boolean
typeof variable === 'boolean'

// Function
typeof variable === 'function'

// Object
typeof variable === 'object'

// RegExp
variable instanceof RegExp

// Array
variable instanceof Array

// null
variable === null

// null or undefined
variable == null

// undefined
typeof variable === 'undefined'

7、类型转换
【建议】转换成字符串类型时使用 + ''

// good
num + '';

// bad
new String(num);
num.toString();
String(num);

【建议】转换成数字类型时,一般情况下可var width = '200px';
parseInt(width, 10);使用+

// good
+str;

// bad
Number(str);

【建议】string转换成number,要转换的字符串结尾包含非数字并期望忽略时,使用parseInt

var width = '200px';
parseInt(width, 10);

【建议】转换成Boolean时,建议使用!!

var num = 3.14;
!!num;

8、对象
【强制】创建新的对象时使用{},不使用new Obejct();

// good
var obj = {};

// bad
var obj = new Object();

【强制】对象创建时,如果一个对象的所有属性均可以不添加引号,则所有属性不得添加引号。

var info = {
    name: 'someone',
    age: 28
};

【强制】对象创建时,如果任何一个属性需要添加引号,则所有属性必须添加'

// good
var info = {
    'name': 'someone',
    'age': 28,
    'more-info': '...'
};

// bad
var info = {
    name: 'someone',
    age: 28,
    'more-info': '...'
};

【强制】不允许修改和扩展任何原生对象和宿主对象的原型。

// 以下行为绝对禁止
String.prototype.trim = function () {
};

【建议】for in遍历对象时,尽量使用hasOwnProperty过滤掉原型中的属性。

var newInfo = {};
for (var key in info) {
    if (info.hasOwnProperty(key)) {
        newInfo[key] = info[key];
    }
}

9、数组
【强制】使用数组字面量[]创建新数组,除非想要创建的是指定长度的数组。

// good
var arr = [];

// bad
var arr = new Array();

【强制】遍历数组不使用for in
解释:数组对象可能存在数字以外的属性, 这种情况下 for in 不会得到正确结果.

var arr = ['a', 'b', 'c'];
arr.other = 'other things'; // 这里仅作演示, 实际中应使用Object类型

// 正确的遍历方式
for (var i = 0, len = arr.length; i < len; i++) {
    console.log(i);
}

// 错误的遍历方式
for (i in arr) {
    console.log(i);
}

【建议】清空数组使用.length=0;

10、函数
【建议】函数体内代码数量控制在50行以内。
函数内代码过多会导致逻辑混乱并且难以维护。

【建议】函数参数数量控制在6个以内,参数过多时可使用对象属性的方式传入。
除去不定长参数以外,函数具备不同逻辑意义的参数建议控制在 6 个以内,过多参数会导致维护难度增大。


沉默术士
29 声望1 粉丝