javascript语言编码规范

2019-11-19  本文已影响0人  北疆小兵

javascript语言编码规范

命名

var loadingModules = {};
var HTML_ENTITY = {};
function hear(theBells) {
}
function TextNode(options) {
}

代码风格

// good
if (condition) {
}

while (condition) {
}

(function () {
})();

// bad
if(condition) {
}

while(condition) {
}

(function() {
})();


// good
var obj = {
    a: 1,
    b: 2,
    c: 3
};

// bad
var obj = {
    a : 1,
    b:2,
    c :3
};

// good
function funcName() {
}

var funcName = function funcName() {
};

funcName();

// bad
function funcName () {
}

var funcName = function funcName () {
};

funcName ();


# good
const obj = {
  firstName: 'Dana',
  lastName: Scally',
};


# bad
const obj = {
  firstName: 'Dana',
  lastName: 'Scally'
};

if(arg) {
  return arg;
} else {
  return false;
}
import CheckBox from './CheckBox';

类型和变量

// good
const a = 1;
const b = 2;

let count = 1;
if (true) {
    count += 1;
}


// bad
var a = 1;
var b = 2;

var count = 1;
if (true) {
    count += 1;
}

       

一个 var 声明多个变量,容易导致较长的行长度,并且在修改时容易造成逗号和分号的混淆

// good
var hangModules = [];
var missModules = [];
var visited = {};

// bad
var hangModules = [],
missModules = [],
visited = {};

变量声明与使用的距离越远,出现的跨度越大,代码的阅读与维护成本越高。虽然JavaScript的变量是函数作用域,还是应该根据编程中的意图,缩小变量出现的距离空间。

条件

使用 === 可以避免等于判断中隐式的类型转换。

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

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

// 字符串为空

// good
if (!name) {
    // ......
}

// bad
if (name === '') {
    // ......
}

// 字符串非空

// good
if (name) {
    // ......
}

// bad
if (name !== '') {
    // ......
}


// 数组非空

// good
if (collection.length) {
    // ......
}

// bad
if (collection.length > 0) {
    // ......
}

// 布尔不成立

// good
if (!notTrue) {
    // ......
}

// bad
if (notTrue === false) {
    // ......
}


// null 或 undefined

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

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



// 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') {
    // ......
}

/ good
function getName() {
    if (name) {
        return name;
    }

    return 'unnamed';
}

// bad
function getName() {
    if (name) {
        return name;
    }
    else {
        return 'unnamed';
    }
}

循环

循环体中的函数表达式,运行过程中会生成循环次数个函数对象

// 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 访问时会动态计算元素个数,此时缓存 length 能有效提高程序性能。

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

逆序遍历可以节省变量,代码比较优化。

var len = elements.length;
while (len--) {
    var element = elements[len];
    // ......
}

类型

类型检测

// 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'

类型转换


// good
num + '';

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

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

// good
parseInt(str, 10);

// bad
parseInt(str);

let num = 3.14;
!!num;
// good
let num = 3.14;
Math.ceil(num);

// bad
let num = 3.14;
parseInt(num, 10);


对象和引用

// good
var obj = {};

// bad
var obj = new Object();
var info = {
    name: 'someone',
    age: 28
};

如果属性不符合 Identifier 和 NumberLiteral 的形式,就需要以 StringLiteral 的形式提供。

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

通常在 JavaScript 中声明的对象,属性命名是使用 Camel 命名法,用 . 来访问更清晰简洁。部分特殊的属性(比如来自后端的 JSON ),可能采用不寻常的命名方式,可以通过 [expr] 方式访问。

info.age;
info['more-info'];

# good
let name = "zhangsan"
const obj = {
    name
}


# bad
let name = "zhangsan"
const obj = {
    name:name
}
       

String

1.输入单引号不需要按住 shift,方便输入。
2.实际使用中,字符串经常用来拼接 HTML。为方便 HTML 中包含双引号而不需要转义写法。

var str = '我是一个字符串';
var html = '<div class="cls">拼接HTML可以省去双引号转义</div>';

function sayHi(name) {
  return `How are you, ${name}`;
}

数组

// good
var arr = [];

// bad
var arr = new Array();

数组对象可能存在数字以外的属性, 这种情况下 for in 不会得到正确结果。

```
# good
const itemsCopy = [...items];

# bad
const len = items.length;
const itemsCopy = [];

let i;
for(i=0; i<len; i++) {
  itemsCopy[i] = items[i];
}

```

函数

除去不定长参数以外,函数具备不同逻辑意义的参数建议控制在 6 个以内,过多参数会导致维护难度增大。

有些函数的参数并不是作为算法的输入,而是对算法的某些分支条件判断之用,此类参数建议通过一个 options 参数传递。

#good
/**
 * 移除某个元素
 *
 * @param {Node} element 需要移除的元素
 * @param {Object} options 相关的逻辑配置
 * @param {boolean} options.removeEventListeners 是否同时将所有注册在元素上的事件移除
 */
function removeElement(element, options) {
    element.parent.removeChild(element);

    if (options.removeEventListeners) {
        element.clearEventListeners();
    }
}

# bad
/**
 * 移除某个元素
 *
 * @param {Node} element 需要移除的元素
 * @param {boolean} removeEventListeners 是否同时将所有注册在元素上的事件移除
 */
function removeElement(element, removeEventListeners) {
    element.parent.removeChild(element);

    if (removeEventListeners) {
        element.clearEventListeners();
    }
}
var emptyFunction = function () {};

箭头函数

# good
    [1, 2, 3].map( (x) => {
        return x * x;
    });
    
    # bad
    [1, 2, 3].map(function(x) {
      return x * x;
    });


```
[1, 2, 3].map( x => x * x;);
```

解构

说明:
ES6允许按照一定的模式, 从数组和对象中提取值、对变量进行赋值, 这称之为解构, 解构赋值避免了临时变量或对象, 给JavaScript书写带来了很大的便利性, 同时也提高了代码的可读性。

# good

let user = {
    firstName: "Jack",
    lastName: "Ma",
};

function getFullName({firstName,lastName}){
    return `${user.firstName} ${user.lastName}`;
}
# bad
function getFullName (user) {
  const firstName = user.firstName;
  const lastName = user.lastName;
  return  `${firstName} ${lastName}`;
}

对象解构在增加属性或改变排序时, 无需改变调用时的位置。

上一篇下一篇

猜你喜欢

热点阅读