node.js中的编码样式

时间:2014-02-26 10:18:39

标签: javascript performance node.js syntax coding-style

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

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中看到,闭包样式在nodejs中比在另一个中更受欢迎。请帮我澄清为什么在nodejs中使用this.something语法不好。

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

7 个答案:

答案 0 :(得分:4)

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

Closure提供对局部变量的访问。这样,您就可以创建无法从外部访问的私有变量(例如示例中的url)。但它会影响性能,因为每次创建对象时都会创建闭包。

原型函数更快,但它是在对象之前创建的,并且对对象本身一无所知。

有时甚至可以同时使用它们。 :)

PS:编码风格在这里描述:https://npmjs.org/doc/coding-style.html。它没有解释你的特定问题,但我觉得我必须在以前的答案中平衡这两个链接,更明智一些。 :)

答案 1 :(得分:1)

正确完成后,闭包允许您通过使用任何其他调用者无法修改的作用域链来封装数据。

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

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

现在它可能不会像那样明确地发生,但是如果你将对象或对象属性作为事件处理程序,回调等传递给其他函数,那么你无法知道 - 或者防止 - 使用这种类型。所以最重要的是,'this'关键字不是您可以依赖的关键字。虽然您可以使用闭包完全控制您的直接范围。

与此类似,您也无法保证您的对象的原型链未被更改。当然,除非你在对象上创建一个闭包并返回一个包装器。

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

答案 2 :(得分:0)

节点遵循javascript标准。所以任何javascript编码风格都是node.js的正确编码风格。但是以下链接可能会为您提供node.js编码样式的缩写。

http://nodeguide.com/style.html

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

答案 3 :(得分:0)

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

===在闭包中定义属性的对象

如果你创建一个对象(让我们自己调用), 在其范围内添加一组访问和附加到该对象的方法(self.x) 并且在最后导出self时,一切只能访问你添加到self的内容,并且无法访问你自己创建的函数内的局部变量

===构造函数和原型

另一方面,如果你创建构造函数并通过原型向它们添加方法/字段,那么每个附加到你的实例的函数都可以访问它的内部变量和状态。

==

有一些事情比使用EventEmitter这样的原型更容易 和Streams但也不太难将它们附加到对象上。

Javascript既是面向对象的语言又是功能语言,缺少双方繁重的工具

像正确的继承曾经见过this.super()。super()。someMethod()??我没有 (如果两个超类具有相同的方法名称,则需要它)

或函数式编程方面的游牧民或简单生成器。

所以对我而言,使用两者都是有道理的,并选择最适合您问题的那个。

修改

我完全忘记的对象有一大好处。 在你的第二个例子中,你使用了一个流控制库(在这种情况下是异步的,但是任何推迟的库都可以),它使你的代码更加清晰,但是

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

答案 4 :(得分:0)

我使用 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);
    }
});

答案 5 :(得分:0)

恕我直言,这是讨论比节点更大......它是关于javascript语言的。

所以我建议你阅读:

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

并且谷歌关于javascript设计模式!

答案 6 :(得分: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是私有变量无法获取或设置

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