接上篇:Felix’s Node.js Style Guide (Part 1)
创建Object / Array
逗号应放在行尾而不是行首,每一行放置简短的变量声明。只在你的解释器抱怨的时候才应该去给array的key上加上引号。 正确: [cc lang=”javascript”] var a = [‘hello’, ‘world’]; var b = { good: ‘code’, ‘is generally’: ‘pretty’, }; [/cc] 错误: [cc lang=”javascript”] var a = [ ‘hello’, ‘world’ ]; var b = {“good”: ‘code’ , is generally: ‘pretty’ }; [/cc]
等号操作符
编程不是仅仅记住那些愚蠢的规则。比如我们应该使用三个等号的相等操作符,因为它会有我们意料之中的行为。 正确: [cc lang=”javascript”] var a = 0; if (a === ‘’) { console.log(‘winning’); } [/cc] 错误: [cc lang=”javascript”] var a = 0; if (a == ‘’) { console.log(‘losing’); } [/cc]
原型扩展
不要扩展任何对象的prototype原型,特别是native的对象。如果你不遵守这条准则,地狱里面某个特殊的地方正在等着你。 正确: [cc lang=”javascript”] var a = []; if (!a.length) { console.log(‘winning’); } [/cc] 错误: [cc lang=”javascript”] Array.prototype.empty = function() { return !this.length; } var a = []; if (a.empty()) { console.log(‘losing’); } [/cc]
条件判断
任何只要不是没用的条件判断都应该被赋予一个有意义具有描述性的变量名: 正确: [cc lang=”javascript”] var isAuthorized = (user.isAdmin() || user.isModerator()); if (isAuthorized) { console.log(‘winning’); } [/cc] 错误: [cc lang=”javascript”] if (user.isAdmin() || user.isModerator()) { console.log(‘losing’); } [/cc]
函数长度
函数尽量保持简短。一个好的函数应该能够完整的放到一张幻灯片里面,且能让一个大会议室的最后一排观众可以轻松舒适的阅读到。所以不要指望他们都有很好的视力,你应该限制你的每个函数都在10行左右。
Return语句
为了避免if语句的深层次嵌套,函数内部尽量越早return越好。 正确: [cc lang=”javascript”] function isPercentage(val) { if (val < 0) { return false; } if (val > 100) { return false; } return true; } [/cc] 错误: [cc lang=”javascript”] function isPercentage(val) { if (val >= 0) { if (val < 100) { return true; } else { return false; } } else { return false; } } [/cc] 就这个例子来说,我们还可以更加简化: [cc lang=”javascript”] function isPercentage(val) { var isInRange = (val >= 0 && val <= 100); return isInRange; } [/cc]
命名闭包
可以给你的闭包取个名字。这意味着你很关心它们,且会产生更好的堆栈跟踪(stack trace)。 正确: [cc lang=”javascript”] req.on(‘end’, function onEnd() { console.log(‘winning’); }); [/cc] 错误: [cc lang=”javascript”] req.on(‘end’, function() { console.log(‘losing’); }); [/cc]
嵌套闭包
使用闭包,但不要嵌套它们。否则你的代码会变的一团糟。 正确: [cc lang=”javascript”] setTimeout(function() { client.connect(afterConnect); }, 1000); function afterConnect() { console.log(‘winning’); } [/cc] 错误: [cc lang=”javascript”] setTimeout(function() { client.connect(function() { console.log(‘losing’); }); }, 1000); [/cc]
回调(Callbacks)
由于node意味着到处都是非阻塞I/O,函数通常都会使用回调函数来返回结果。node核心开发小组的惯例是保留回调函数的第一个参数,以用来存储可能存在的error对象。 你应该在你自己的回调函数里使用相同的方法。
Object.freeze, Object.preventExtensions, Object.seal, with, eval
这些都是些疯狂的东西,你很有可能永远不需要它们。远离它们。
Getters and setters
不要使用setters,它们会产生远比它能解决的麻烦多的多的麻烦。 可以在不产生副作用的时候使用getters,比如给你的集合类提供一个length属性。
EventEmitters
Node.js自带了一个简单的EventEmitter类,它可以从’event’模块里面进行include: [cc lang=”javascript”] var EventEmitter = require(‘events’).EventEmitter; [/cc] 在创建复杂的类的时候,继承这个EventEmitter类来用来产生事件是很常见的做法。这基本上就是一个简单的观察者模式的实现。 不过,我强烈建议你不要在你自己的类里面监听它自己所发出的事件。让一个对象监听它自己是很不自然的。它经常还会以你不希望的形式将你的实现细节暴露出来,同时让你的代码更难看懂。
继承 / 面向对象编程
继承和面向对象编程它们本身各自都是主题。如果你对这个流行的编程模型有兴趣,请阅读我的面向对象编程指南。