附录 B Node.js编程规范 - Node.js开发指南

返回介绍

附录 B Node.js编程规范

发布于 2017-06-21 字数6513 浏览 943 评论 0

并没有一个官方的文档规定Node.js应用程序代码的风格,但Node.js代码分割有着一些“事实上的约定”,大多数项目的代码都一定程度上遵循了这一标准。作为Node.js开发新手,我认为有必要遵守这个约定,以便于今后的交流。追根溯源,这个规范发轫于Node.js核心模块的实现,而Node.js核心模块的代码很大程度上符合JavaScript代码的一贯风格。

事实上代码风格永远是一个有争议的话题,没有什么最好的,也不可能被所有人认可。我们在这一章节介绍的规范主要参考了“Felix’s Node.js Style Guide”(http://nodeguide.com/style.html),其中不仅有代码风格上的规范,也有JavaScript特性选择和设计模式上的建议,这些建议都是经验之谈,并非必须遵守,但可能会让你的程序避免很多意外的错误和性能损失。让我们开始介绍吧。

B.1 缩进

在早期的语言规范中,大多数都选择用Tab作为缩进标记,如Delphi、Microsoft C++规范等。但近年来,空格缩进依靠其风格的不变性,逐渐成为了主流。

如Python、Ruby甚至C#都采用了空格缩进作为“标准”。但我们选择 两空格 作为Node.js代码的缩进标记,不同于最常见的四空格缩进。这是因为Node.js代码中很容易写出深层的函数嵌套,过多的空格会给阅读带来不便,因此我们选择两空格缩进。

正确的缩进:

function func(boolVar) {
    if (boolVar) {
        console.log('True');
    } else {
        console.log('False');
    }
};

错误的缩进:

function func(boolVar)
{
    if (boolVar)
    {
        console.log('True');
    }
    else
    {
        console.log('False');
    }
};

B.2 行宽

尽管现在你的显示器屏幕可能已经很宽了,但为了保证在任何设备上都可以方便地阅读,我们建议把行宽限制为80个字符。

B.3 语句分隔符

JavaScript不仅支持像C语言一样的分号( ; )作为语句之间的分隔符,还支持像Python语言那样的换行作为语句之间的界限。我们建议一律使用分号,哪怕一行只有一个语句,也不要省略分号。

正确的语句分隔:

var a = 1;
var b = 'world';
var c = function(x) {
    console.log('hello ' + x + a);
};
c(b);

错误的语句分隔:

var a = 1
var b = 'world'
var c = function(x) {
    console.log('hello ' + x + a)
}
c(b)

B.4 变量定义

永远使用 var 定义变量,而不要通过赋值隐式定义变量。因为通过赋值隐式定义的变量总是全局变量,会造成命名空间污染。我们建议绝不使用全局变量,因此要通过 var 把所有变量定义为局部变量。

使用 var 定义变量时,确保每个语句定义一个变量,而不要通过逗号( , )把多个变量隔开。

正确的变量定义格式:

var foo;
var bar;
var arr = [40, 'foo'];
var obj = {};

错误的变量定义格式:

var foo, bar;
var arr = [40, 'foo'],
obj = {};

B.5 变量名和属性名

我们使用小驼峰式命名法(lower camel case)作为所有变量和属性的命名规则,不建议使用任何单字母的变量名。

正确的命名:

var yourName = 'BYVoid';

错误的命名:

var YourName = 'BYVoid';
//或者
var your_name = 'BYVoid';

B.6 函数

JavaScript具有函数式编程的特性,因此函数本质上和一般的变量没有区别,对于一般的函数我们同样使用小驼峰式命名法。但对于对象的构造函数名称(或者不严格地说“类”的名称),我们使用大驼峰式命名法(upper camel case),也称为Pascal命名法。

规定函数名与参数表之间规定无空格,参数表和括号( { 和 } )之间要有一个空格,并且在同一行。

正确:

var someFunction = function() {
    return 'something';
};
function anotherFunction() {
    return 'anything';
}
function DataStructure() {
    this.someProperty = 'initialized';
}

错误:

var SomeFunction = function()
{
    return 'something';
};
function another_function () {
    return 'anything';
}
function dataStructure() {
    this.someProperty = 'initialized';}

B.7 引号

JavaScript中单引号( ‘ )和双引号( ” )没有任何语义区别,两者都是可用的。我们建议一律统一为单引号,因为JSON、XML都规定了必须是双引号,这样便于无转义地直接引用。

正确的引号用法:

console.log('Hello world.');

错误的引号用法:

console.log("Hello world.");

B.8 关联数组的初始化

将 var = { 放在一行,下面每行一对键值,保持两空格的缩进,以分号结尾,}; 最后单独另起一行。对于每对键值,除非键名之中有空格或者有非法字符,否则一律不用引号。

正确:

var anObject = {
    name: 'BYVoid',
    website: 'http://www.byvoid.com/',
    'is good': true,
};

错误:

var anObject = {'name': 'BYVoid',
                website: 'http://www.byvoid.com/'
                , "is good": true};

B.9 等号

尽量使用 === 而不是 == 来判断相等,因为 == 包含了隐式类型转换,很多时候可能与你的预期不同,例如下面错误的例子,num == literal的值是true。

正确的等号用法:

var num = 9;
var literal = '9';
if (num === literal) {
    console.log('Should not be here!!!');
}

错误的等号用法:

var num = 9;
var literal = '9';
if (num == literal) {
    console.log('Should not be here!!!');
}

B.10 命名函数

尽量给构造函数和回调函数命名,这样当你在调试的时候可以看见更清晰的调用栈。对于回调函数,Node.js的API和各个第三方的模块通常约定回调函数的第一个参数是错误对象err,如果没有错误发生,其值为 undefined。

正确:

req.on('end', function onEnd(err, message) {
    if (err) {
        console.log('Error.');
    }
});
function FooObj() {
    this.foo = 'bar';
}

错误:

req.on('end', function (message, err) {
    if (err === false) {
        console.log('Error.');
    }
});
var FooObj = function() {
    this.foo = 'bar';
}

B.11 对象定义

尽量将所有的成员函数通过原型定义,将属性在构造函数内定义,然后对构造函数使用new 关键字创建对象。绝对不要把属性作为原型定义,因为当要定义的属性是一个对象的时候,不同实例中的属性会指向同一地址。除非必须,避免把成员函数定义在构造函数内部,否则会有运行时的闭包开销。

正确:

function FooObj(bar) {
    //在构造函数中初始化属性
    this.bar = bar;
    this.arr = [1, 2, 3];
}
//使用原型定义成员函数
FooObj.prototype.func = function() {
    console.log(this.arr);
};
var obj1 = new FooObj('obj1');
var obj2 = new FooObj('obj2');
obj1.arr.push(4);
obj1.func(); // [1, 2, 3, 4]
obj2.func(); // [1, 2, 3]

错误:

function FooObj(bar) {
    this.bar = bar;
    this.func = function() {
        console.log(this.arr);
    };
}
FooObj.prototype.arr = [1, 2, 3];
var obj1 = new FooObj('obj1');
var obj2 = new FooObj('obj2');
obj1.arr.push(4);
obj1.func(); // [1, 2, 3, 4]
obj2.func(); // [1, 2, 3, 4]

B.12 继承

首先,避免使用复杂的继承,如多重继承或深层次的继承树。如果的确需要继承,那么尽量使用Node.js的util模块中提供的inherits函数。例如我们要让Foo继承EventEmitter,最好使用以下方式:

var util = require('util');
var events = require('events');
function Foo() {
}
util.inherits(Foo, events.EventEmitter);

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

目前还没有任何评论,快来抢沙发吧!