Node.JS编码规范指南教程:教你优雅地写JavaScript代码


发布者 ourjs  发布时间 1416383295764
关键字 JS学习  Node.JS 
注* 仅供参数

这是用于书写一致性和优美的node.js代码的指南教程。它由社区维护并在社区内流行,参考了一些人的意见。

我们维护了一个.jshintrc来强制执行这些规则(自动格式化参数配制)。您可以使用并进行调整,或者编写自己的脚本。

本指南是由费利克斯Geisendörfer创建,并遵守CC BY-SA3.0许可授权。我们鼓励您根据自己的喜好进行调整。


2个空格的缩进


使用2个空格进行缩进,永远也不要使用混合的tab和空格作为缩进。

换行


使用Unix风格的换行,每行结尾以(\n)结束,永远不要使用Windows的换行符(\r\n)。

无拖尾空白


永远也不要在一行后面留空格,在提交之前,你要像每顿饭刷牙一样清理你的JS文件。否则,腐烂的气味会驱走贡献者或同事。

使用分号


根据科学研究,分号的使用是我们社会的核心价值。考虑一下反对派的观点 ,但是我们需要传统,不要滥用纠错机制(省略分号)。

注* 在JavaScript中前置逗号代码风格和省略分号一直存在争论,下同。

每行最多80个字符


每行最多80个字符。是的,屏幕在最近几年越来越大,但是你的脑子没怎么变,你可以使用多余的空间用来分屏。

使用单引号


只有在JSON文件中才使用双引号


Right:

var foo = 'bar';


Wrong:

var foo = "bar";


注* 为什么? JavaScript中包含双引号的字符串几乎到处都是,这样你就不需要转义了。


在同一行写大括号



Right:

if (true) {
  console.log('winning');
}

Wrong:

if (true)
{
  console.log('losing');
}

同样,注意在条件前后都加个空格。


方法链(调用链)


如果你使用方法链,确保每行只调用一个方法。

同时你要合理使用缩进来表示他们的父对象是一致的。


Right:

User
  .findOne({ name: 'foo' })
  .populate('bar')
  .exec(function(err, user) {
    return true;
  });



Wrong:

User
.findOne({ name: 'foo' })
.populate('bar')
.exec(function(err, user) {
  return true;
});
User.findOne({ name: 'foo' })
  .populate('bar')
  .exec(function(err, user) {
    return true;
  });
User.findOne({ name: 'foo' }).populate('bar')
.exec(function(err, user) {
  return true;
});
User.findOne({ name: 'foo' }).populate('bar')
  .exec(function(err, user) {
    return true;
});


每行声明一个变量


每个var只声明一个变量,它可以更容易地重新排序。但是,并且变量应该在更有意义的地方声明。

Right:

var keys   = ['foo', 'bar'];
var values = [23, 42];
var object = {};
while (keys.length) {
  var key = keys.pop();
  object[key] = values.pop();
}


Wrong:

var keys = ['foo', 'bar'],
    values = [23, 42],
    object = {},
    key;
while (keys.length) {
  key = keys.pop();
  object[key] = values.pop();
}



使用首字母小写给变量属性和函数命名


变量,属性和函数名应该使用lowerCamelCase(首字母小写)。他们也应该是描述性的。一般应避免单字符变量和不常见的缩写。

Right:

var adminUser = db.query('SELECT * FROM users ...');

Wrong:

var admin_user = db.query('SELECT * FROM users ...');


类名首字母大写


类名的首字母应该是大写的

Right:

function BankAccount() {
}

Wrong:

function bank_Account() {
}


常量大写



常量应该被声明为普通变量或静态类的属性,全部使用大写字母。

Node.js/V8实际上支持Mozilla的const的扩展,但遗憾的是不能用于类成员,也不是任何ECMA标准的一部分。

Right:

var SECOND = 1 * 1000;

function File() {
}
File.FULL_PERMISSIONS = 0777;

Wrong:

const SECOND = 1 * 1000;

function File() {
}
File.fullPermissions = 0777;


Object / Array 声明


使用尾随逗号,把短的声明在一行:

Right:

var a = ['hello', 'world'];
var b = {
  good: 'code',
  'is generally': 'pretty'
};

Wrong:

var a = [
  'hello', 'world'
];
var b = {"good": 'code'
        , "is generally": 'pretty'
        };


使用 === 操作符


编写不应该只记事规则,还要学会使用。

Right:

var a = 0;
if (a !== '') {
  console.log('winning');
}

Wrong:

var a = 0;
if (a == '') {
  console.log('losing');
}

注* === 即会判断类型,又会判断结果。


使用多行三元运算符


三元运算符不应该用在一行。分割成多行来代替。

Right:

var foo = (a === b)
  ? 1
  : 2;

Wrong:

var foo = (a === b) ? 1 : 2;



不要扩展内置对象



不要扩展原生JavaScript对象的原型。以后会后悔的。


Right:

var a = [];
if (!a.length) {
  console.log('winning');
}


Wrong:

Array.prototype.empty = function() {
  return !this.length;
}
var a = [];
if (a.empty()) {
  console.log('losing');
}


注* 扩展String.prototype是比较常见的,如format, trim。



使用描述性的条件


任何判断条件应该分配给一个描述性命名的变量或函数:

Right:

var isValidPassword = password.length >= 4 && /^(?=.*\d).{4,}$/.test(password);

if (isValidPassword) {
  console.log('winning');
}


Wrong:

if (password.length >= 4 && /^(?=.*\d).{4,}$/.test(password)) {
  console.log('losing');
}


写小而短的函数


保持你的函数短一点。对一个大房间的最后一排的人民群众而言可以轻松读取幻灯片上的代码是比较合适的。不要指望他们有的视力保持每个函数〜15行代码。


早点从函数返回


为了避免if语句的深层嵌套,总是尽可能早地在函数返回值。


Right:

function isPercentage(val) {
  if (val < 0) {
    return false;
  }
  if (val > 100) {
    return false;
  }
  return true;
}


Wrong:

function isPercentage(val) {
  if (val >= 0) {
    if (val < 100) {
      return true;
    } else {
      return false;
    }
  } else {
    return false;
  }
}


命名您的闭包


随时给你闭包名称。这表明你关心他们,并能产生更好的堆栈跟踪,heap和cpu profiles。

Right:

req.on('end', function onEnd() {
  console.log('winning');
});

Wrong:

req.on('end', function() {
  console.log('losing');
});


不要嵌套闭包


使用闭包,但不能嵌套他们。否则,你的代码会变得一团糟。

Right:

setTimeout(function() {
  client.connect(afterConnect);
}, 1000);
function afterConnect() {
  console.log('winning');
}


Wrong:

setTimeout(function() {
  client.connect(function() {
    console.log('losing');
  });
}, 1000);



使用斜线注释


使用斜线为单行和多行注释。尝试从更高层次说明你代码的意图。不要重申琐碎的事情。


Right:

// 'ID_SOMETHING=VALUE' -> ['ID_SOMETHING=VALUE', 'SOMETHING', 'VALUE']
var matches = item.match(/ID_([^\n]+)=([^\n]+)/));
// This function has a nasty side effect where a failure to increment a
// redis counter used for statistics will cause an exception. This needs
// to be fixed in a later iteration.
function loadUser(id, cb) {
  // ...
}
var isSessionValid = (session.expires < Date.now());
if (isSessionValid) {
  // ...
}


Wrong:

// Execute a regex
var matches = item.match(/ID_([^\n]+)=([^\n]+)/));
// Usage: loadUser(5, function() { ... })
function loadUser(id, cb) {
  // ...
}
// Check if the session is valid
var isSessionValid = (session.expires < Date.now());
// If the session is valid
if (isSessionValid) {
  // ...
}

禁止使用: Object.freeze, Object.preventExtensions, Object.seal, with, eval


这些功能很可笑,远离他们。

注* 类似Java/C#中的protected / private / seal / final。







回复 (12)
  • #
  • #1 ourjs 1416389361497

    What?

  • #2 易妇牛 1416447887589

    有很多都不是很赞同。

  • #3 易妇牛 1416447928487

    关于javascript的文章越来越少了啊!注意了

  • #4 ourjs 1416448071101

    @易妇牛 #2

    欢迎分享贡献

  • #5 吕尘寺 1416457858860

    赞一下

  • #6 Redstone 1416471814642

    非常好。不过我需要根据这个规范转成一个coffee的规范。

  • #7 关仗见 1416492984859

    Object / Array 声明处,正确写法中有错误,那个b的对象多一个“,”这样会导致网页错误,在IE6的浏览器下。

  • #8 ourjs 1416524420326

    @关仗见 #6

    确实如此,已经更正,这位小哥可在原文github上提一个pull request。

  • #9 席米仰 1438653846218

    @ourjs #7

    额 他这个是nodejs的。。。。不管ie

  • #10 姜王勺 1475893380406

    禁止使用: Object.freeze, Object.preventExtensions, Object.seal, with, eval

    这是为什么?

  • #11 卫他任 1487575905026

    不要扩展内置对象这一条有点以偏概全了吧?只要做好兼容的话,自己写扩展方法也是一种很好的选择。如扩展Array的forEach方法: Array.prototype.forEach=Array.prototype.forEach||function(...) {...自己的扩展方法}

    除非有专定烂代码爱好的人,上面的函数在很多场合都正常使用

  • #12 常乏甘 1510313721842

    @易妇牛 #2

    我从Java走来,尝了尝js的苦与甜,最后又默默地回去了我的大Java。下一步计划尝一尝 go

微信扫码 立即评论