在node.js中的编码风格

样式1: 具有构造函数/原型的对象

function DB(url) { this.url = url; } DB.prototype.info = function (callback) { http.get(this.url + '/info', callback); }; 

样式2: closures

 function DB(url) { return { info: async.apply(http.get, url + '/info') }; } 

这只是一个例子,假设涉及更多的原型方法和私有方法。

我已经在post1和2中看到,闭包风格在nodejs中比其他更受欢迎。 请帮我澄清为什么在nodejs中使用this.something语法不好。

你可以给出你的意见,哪一个更好,但我最需要知道什么是在nodejs中使用每种风格的优点和缺点

这不是一个风格。 这两个函数做两个完全不同的事情。

Closure提供对局部variables的访问。 这样你就可以创build不能从外部访问的私有variables(比如你的例子中的url )。 但是,由于每次创build对象时都会创build闭包,所以会产生性能影响。

原型函数速度更快,但它是在对象之前创build的,并不知道对象本身的任何内容。

有时甚至同时使用它们也是有意义的。 🙂

PS:编码风格在这里描述: https : //npmjs.org/doc/coding-style.html 。 这并不能解释你的具体问题,但我觉得我必须在以前的回答中把这两个环节与更明智的东西进行平衡。 🙂

当正确完成时,闭包允许你通过使用范围链来封装数据,这个链不能被任何其他调用者修改。

原型链不具有同样意义上的任何保护。 以您所描述的方式使用对象的主要缺点,尤其是在服务器或库场景中,“this”关键字可以由调用者修改。 你无法控制这个,如果发生的话你的代码将会以非常难以预料的方式破解。

 var mongo = new DB('localhost'); mongo.info.call(this); // broken 

现在,它可能不会像那样明确地发生,但是如果将事件处理程序,callback函数等对象或对象属性传递到其他函数中,则无法知道或防止该types的用法。 所以底线是“这个”关键字是不是你可以存储的。 虽然你可以完全控制你的眼前的范围,使用闭包。

同样,你也不能保证你的对象的原型链没有被改变。 当然,除非你在对象上创build一个闭包并返回一个包装。

最后,封闭结构更接近德米特定律,因为在理论上,你的目的是通过原型链“达成”。 使用闭包来封装其他调用,可以使您公开一个可能导致调用另一个服务方法的方法。 这提供了更大的可维护性和灵活性,因为您现在可以直接控制您公开的方法而不依赖原型链。 当然,LoD只是一种做事的方式,对你来说可能是重要的,也可能不重要。

节点遵循JavaScript标准。 所以任何javascript编码风格对于node.js来说都是合适的编码风格。 但下面的链接可能会给你node.js编码风格的缩写。

http://nodeguide.com/style.html

http://innofied.com/javascript-coding-standards-follow/

我使用sjsClass : https : //www.npmjs.org/package/sjsclass

代码示例:

 Class.extend('DB', { 'protected url': null, __constructor: function (url) { this.url = url; }, info: function (callback) { http.get(this.url + '/info', callback); } }); 

这两种风格都有好处,我认为这取决于你的模块/文件试图公开。 我大量使用闭包风格的大多数模块,我在我的代码中使用。 (如数据库抽象,caching抽象,邮件等),我使用构造函数/对象的原型创build了很多(如双链表中的节点)

===具有在闭包内定义的属性的对象

如果你创build一个对象(让我们自己调用它),在它的范围内添加一堆访问和附加到该对象(self.x)的方法,并在结束时导出自己,一切都只能访问你添加到自己和不能访问您创build自我的函数内部的局部variables

===构造函数和原型

另一方面,如果您创build构造函数并向其添加方法/字段,那么每个附加到您实例的函数都可以访问其内部variables和状态。

==

有些东西比如EventEmitter和Streams等原型更容易工作,但是将它们附加到对象上也不是很困难。

Javascript既是一种面向对象的语言,又是一种function性的语言,同时也忽略了双方的繁重工具

像正确的inheritance有史以来this.super()。super()。someMethod()? 我没有(你需要它,如果两个超类有相同的方法名称)

或function性编程方面的游牧民族或简单的发电机。

所以对我来说,使用两者都是有意义的,并select一个最适合你的问题。

编辑

对于我完全忘记的对象有一个很大的好处。 在你的第二个例子中,你使用了一个stream控制库(在这个例子中是asynchronous的,但是任何一个被攻击的库都会这么做),但是它使得你的代码更加清洁

为你的例子工作http.get的get方法必须绑定到http,在许多情况下,它不是。 所以那么你的代码将看起来像http.get.bind(http),如果http是一个对象,并得到在其范围内定义它将始终工作,并允许您传递给其他代码。 (如asynchronous)

恕我直言,这是讨论比节点大…这是关于JavaScript语言。

所以我build议阅读这个:

http://addyosmani.com/resources/essentialjsdesignpatterns/book/

和谷歌关于JavaScriptdevise模式律!

构造函数可以这样使用

 var db = new DB(); ... if(db instanceof DB){ ... } 

闭包可以使私有variables像

 function DB(url) { var urlParam = '&a=b'; return { info: async.apply(http.get, url + '/info' + urlParam) }; } 

urlParam是一个私有variables,不能被获取或设置

如果您只想要静态类或简单类,请使用闭包。