2014-02-26 77 views
1

样式1:对象与构造/原型在node.js中编码风格

function DB(url) { 
    this.url = url; 
} 

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

样式2:瓶盖

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

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

我已阅读的帖子OneTwo闭包风格比nodej更优先于另一个。请帮我澄清为什么在nodejs中使用this.something语法不好。

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

回答

0

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

http://nodeguide.com/style.html

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

+0

但这两个链接都没有提到我提到的特定风格。 N其次,我认为你错了,说节点遵循JavaScript风格,因为NODE是一个不同的平台,它可以有不同的约定和风格,在浏览器中不是典型的JavaScript。 –

+0

对于任何平台,JavaScript的编码标准都应该相同。它可能取决于使用。回调函数,事件和节点中的许多事物与基本JavaScript相同 – Kundu

+0

@Saransh Node *是* Javascript。您不能以除JavaScript之外的任何其他样式编写节点。 – Barney

4

这不是一个风格。这两个功能完成两个完全不同的事情。

Closure提供对局部变量的访问。通过这种方式,您可以创建不可从外部访问的私有变量(例如,在您的示例中为url)。但是它会产生性能影响,因为每次创建对象时都会创建闭包。

Prototype函数速度更快,但它是在对象之前创建的,并且不知道任何关于对象本身的东西。

有时甚至在同一时间使用它们也是有意义的。 :)

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

+0

什么使用两者同时有意义?我认为你指的是我应该根据我正在编写的那段特定代码的需要来使用它们。但是,如果是这种情况,我想知道哪种情况下我应该使用哪一种....这是我的问题 –

+0

“两者同时”意味着根据传递给构造函数的选项来覆盖某些方法的能力。如果你不知道我在说什么,只需使用'prototype',因为它更快。 – alex

+0

你可以建议我一个例子,其中两个都使用?我完全不理解它。 –

0

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

===具有内部属性的对象一个封闭

如果您在其范围内创建一个对象(让我们称它为self), 添加一堆访问并附加到该对象的方法(self。X) ,并在年底的出口自我,一切都只能访问您添加到自己什么,不能访问,你对其他创建自

===构造函数和原型

函数内部的局部变量如果您创建构造函数并向它们添加方法/字段,则可以使用原型的每个附加到您实例的函数都可以访问其内部变量和状态。

==

有一些事情,与像EventEmitter 和流原型的工作更容易,但它不是很难它们也附加到的对象。

JavaScript是既面向对象语言和函数式语言,并在双方

像适当的继承见过this.super()。超()缺少重型起重工具。的someMethod()?我没有 (如果两个超类都有相同的方法名称,你需要它)

或功能性编程侧的游牧民族或简单生成器。

所以对我来说,使用两者都有意义,并选择最适合您的问题的。

编辑

存在对我完全忘了对象的一个​​很大的好处。 在第二个例子中,你(在这种情况下异步但是任何延迟执行库都可以)使用流量控制库,它使你的代码,以便更清洁,但

为您例如工作的http.get有get方法绑定到http,在很多情况下它不是。那么你的代码看起来像http.get.bind(http) 如果http是一个对象,并且get在它的作用域中被定义,它将始终工作,并允许你将它传递给其他代码。 (如异步)

0

我用sjsClasshttps://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); 
    } 
}); 
1

瓶盖,当正确完成,允许您通过使用范围链的,可以不封装数据由任何其他调用者修改。

原型链并不提供任何保护。以您所描述的方式使用对象的主要缺点是,特别是在服务器或库场景中,可以通过调用者修改“this”关键字。你无法控制它,如果它发生,你的代码将以非常不可预知的方式破解。

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

现在,它可能不是明确的,但如果你身边掠过对象或对象属性,事件处理程序,回调等为其他功能发生,因为,你有没有办法知道 - 或保护对抗 - 该类型的使用。所以底线是“这个”关键字不是你可以存储的。尽管你可以使用闭包完全控制你的直接范围。

以类似的方式,你也不能保证你的对象的原型链没有被改变。当然,除非你在对象上创建一个闭包并返回一个包装。

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

+0

因此,如果API必须公开,那么您是否倾向于使用闭包;如果其内部应用程序仅由我开发,那么我认为原型是安全的? –

+0

是的,这两种方式都不会有固有的性能问题。这是一种风格选择,闭包更受保护 - 更接近私人实例变量。但是有两种框架和插件可以实现这一点,所以最终对您有所帮助。我还要指出,至少,CommonJS模块使闭包易于使用。但这取决于您的偏好。 –

0

构造可以是这样的

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

闭包可以使私有变量,如

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

urlParam是一个私有变量无法获取或设置

如果你只想要一个静态班级或简单班级,请使用闭包。