[关闭]
@WrRan 2016-09-29T06:15:35.000000Z 字数 4188 阅读 1067

前言

大家都遵从编码规范时,可以让熟悉该规范的人集中于代码的逻辑而非具体的风格上,不仅可以减少bug的可能,还可以有效提高效率。下面介绍Node的编码规范。

编码规范

语言相关

变量声明

使用var声明变量,同时每一行只声明一个变量。

  1. // 正确示例
  2. var assert = require('assert');
  3. var fork = require('child_process').fork;
  4. var net = require('net');
  5. var EventEmitter = require('events').EventEmitter;
  6. //错误示例
  7. var assert = require('assert')
  8. , fork = require('child_process').fork
  9. , net = require('net')
  10. , EventEmitter = require('events').EventEmitter;

比较操作

在比较操作中,尽量使用===代替==,另外当判断假值时,应当省略===或者==。如:

  1. if ('0' === '0') {
  2. // code goes here ...
  3. }
  4. if (!foo) {
  5. // code goes here ...
  6. }

字面量

尽量使用{}/[]来代替new Object()/new Array(),尽量不要使用string/bool/number对象类型,即尽量不要使用new String()/new Boolean()/new Number()

作用域

  1. 避免使用with
  2. 谨慎使用eval()

数组和对象

  1. 字面量格式
    创建对象或者数组时,注意在结尾用逗号分隔。如果分行,一行只放一个元素。
  2. for in循环
    只针对对象使用,不对数组使用。
  3. 不要把数组当做对象使用

缩进

使用2个空格作为缩进,而不是tab缩进。

符号使用

空格

操作符前后都加上空格;另外在小括号前后也加上空格。
下面是正确示例:

  1. var foo = 'bar' + baz;
  2. if (true) {
  3. // code goes here ...
  4. }

下面是错误示例:

  1. var foo='bar'+baz;
  2. if(true) {
  3. // code goes here ...
  4. }

单双引号

node中尽量使用单引号;在JSON中要求所有字符串都使用双引号,内容中出现双引号时需要转义。

大括号

一般情况下,大括号无需另起一行。
下面是正确示例:

  1. if (true) {
  2. // code goes here ...
  3. }

下面是错误示例:

  1. if (true)
  2. {
  3. // code goes here ...
  4. }

逗号

逗号用于元素声明的分割或是元素的分割,如果逗号不在行结尾时,后面需要加一个逗号;且逗号不允许出现在行首。
下面是正确示例:

  1. var foo = 'hello', bar = 'world'; // 但注意变量声明时不应在同一行
  2. var hello = {
  3. foo: 'hello',
  4. bar: 'world'
  5. };
  6. var world = ['hello', 'world'];

分号

在表达式结尾务必添加分号。

命名规范

  1. 变量
    采用小驼峰式命名,即除了第一个单词的首字母不大写外,每个单词的首字母都大写,词与词之间没有任何符号,如:adminUser
  2. 方法
    采用小驼峰式命名。

  3. 采用大驼峰式命名,即所有单词的首字母都大写,如:var User = function() {}
  4. 常量
    所有单词的所有字母都大写,并用下划线分割,如:PINK_COLOR
  5. 文件
    文件命名时,使用下划线连接单词,如child_process.js

NodeJS相关

异步

  1. 异步回调函数的第一个参数应该是错误指示
  2. 在异步方法中一旦有回调函数传入,一定要执行它,且只执行一次

类继承

使用node推荐的方法,如下:

  1. function Socket(options) {
  2. // ...
  3. stream.Stream.call(this);
  4. // ...
  5. }
  6. util.inherits(Socket, stream.Stream); // <= Here

模块导出

所有供外部调用的方法或变量均需要挂载在exports变量上,当需要将一个文件当做一个类导出时,需要通过如下的方式挂载:

  1. module.exports = Class;

注解规范

该部分注解需要配置JSDoc,每个注解的具体含义可以参见JSDoc - 中文文档

文件注解

node中,大部分为将定义为模块,但是会出现部分配置文件,此时可以参考如下注解:

  1. /**
  2. * @file 该文件的主要用途
  3. * @author 作者姓名 <作者邮箱>
  4. */

模块注解

node中,文件即模块,在创建每一个模块时,就需要遵从该部分注解的格式,如下:

  1. /**
  2. * @module 模块名
  3. * @desc 描述该模块的主要用途
  4. * @version 该模块的版本号
  5. *
  6. * @author 作者姓名 <作者邮箱>
  7. */

类型注解

JavaScript是弱类型语言,但当我们对变量的类型提出一定要求时,可以如下注解:

  1. /**
  2. * @type {(string|Array.<string>)}
  3. */
  4. var foo;
  5. /** @type {number} */
  6. var bar = 1;

JSDoc 3中的@type提供了多个定义类型的方法,常用的有:

  1. 直接指定类型名称,如 {Boolean}
  2. 指定为某个类型,但可能为空,如:{?Number}
  3. 指定为某个类型,当一定不为空,如:{!Number}
  4. 指定多个类型名,意为类型为其中之一,如{Boolean|Number}
  5. 数组类型,如:{Array.}或者指出元素类型的{string[]}
  6. 对象类型,如:{Object.}或者指出对象结构的{a: number, b: string, c}(具有属性a,b,c且a为数字,b为字符串,c为任何类型的对象类型)

方法注解

一般方法应当如下注解,注意这不包括参数中含有回调函数的情况。

  1. /**
  2. * 描述方法的主要用途
  3. * @param {string} requiredStringParameter - this is a required parameter, you should give me :)
  4. * @param {number} [defaultValueParam=666] - this is a parameter with default value
  5. * @param {number} [optionalNumberParam] - this is an optional parameter, you give me if you need
  6. * @returns {string|number} - type of the result may be string or number.
  7. */
  8. function someThing(requiredStringParameter, defaultValueParam, optionalNumberParam) {
  9. defaultValueParam = (defaultValueParam === undefined ? 666 : defaultValueParam);
  10. if (optionalNumberParam) {
  11. var num = 0;
  12. return num;
  13. }
  14. else {
  15. var str = "this a demo";
  16. return str;
  17. }
  18. }

还有一种特别的参数类型,接受可变数量的方法,注解如下:

  1. /**
  2. * 累加并输出和
  3. * @param {...number} num - 数字数组
  4. * @returns {number} tot - 参数总和
  5. */
  6. function sum(nums) {
  7. var n = arguments.length;
  8. var tot = 0;
  9. for(var i=0; i<n; ++i)
  10. tot += nums[i];
  11. return tot;
  12. }

回调函数注解

这部分需要了解JSDoc 3的名称路径
根据回调函数是实例方法(instance method),静态方法(static method),内部方法(inner method)的不同,在注解的方式上也会有细微的不同。先看看回调函数为内部方法的注解:

  1. /** @class */
  2. function Requester() {
  3. /**
  4. * @callback Requester~requestCallback
  5. * @param {number} responseCode
  6. * @param {message} responseMessage
  7. */
  8. function requestCallback(responseCode, responseMessage) {}
  9. }
  10. /**
  11. * send a Requester
  12. * @param {Requester~requestCallback} cb - The callback that handles the response
  13. */
  14. Requester.prototype.send = function(cb) {
  15. //code
  16. };

下面这个则是回调函数为全局函数时的注解实例:

  1. /** @class */
  2. function Requester() {}
  3. /**
  4. * send a Requester
  5. * @param {requestCallback} cb - The callback that handles the response
  6. */
  7. Requester.prototype.send = function(cb) {
  8. //code
  9. };
  10. /**
  11. * @callback requestCallback
  12. * @param {number} responseCode
  13. * @param {message} responseMessage
  14. */
  15. function requestCallback(responseCode, responseMessage) {}

同理,可以得到回调函数为静态方法的注解方式,此处从略。

变量注解

JSDoc 3中描述变量的注解丰富,但是鉴于根据Javascipt的语法,我们常常可以知道变量的作用域等信息。故此处仅针对部分特殊的变量做出注解要求。

常量注解

在JavaScript没有真正的常量,但当我们在逻辑上需要常量时,可以如下注解:

  1. /**
  2. * RGB下的颜色常量 - 红色
  3. * @const
  4. * @default 0xFF0000
  5. */
  6. var RED = 0xFF0000;
  7. /**
  8. * 项目根路径
  9. * @const
  10. * @default
  11. */
  12. var ROOT = '/path/to/root';

枚举注解

枚举多用来描述一些静态属性值的集合,应当如下注解:

  1. /**
  2. * Enum for tri-state values.
  3. * @readonly
  4. * @enum {number}
  5. */
  6. var triState = {
  7. /** The true value */
  8. TRUE: 1,
  9. FALSE: -1,
  10. /** @type {boolean} */
  11. MAYBE: true
  12. };

其他

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注