我正在为request
模块构建一个组合,但是我不确定在JS中为Node构建对象的最佳实践是什么。
选择1:
function RequestComposite(request) {
return {
get: function (url) { return request.get(url); }
}
}
var comp = RequestComposite(request);
- 注意:我知道我应该以异步方式调用CB,但为了便于解释,我返回它...
备选方案二:
function RequestComposite(request) {
this.request = request;
}
RequestComposite.prototype.get = function (url) { return this.request.get(url); };
var comp = new RequestComposite(request);
备选方案3:
var RequestComposite = {
init: function (request) { this.request = request; },
get: function (url) { return request.get(url); }
}
var comp = Object.create(RequestComposite).init(request);
我试着找到我的路,然而我对如何使用对象感到更加困惑...
如果我想在浏览器中使用对象,答案会有所不同吗?
谢谢。
3条答案
按热度按时间dz6r00yl1#
最有效的方法如下:
.prototype
属性中设置方法。为什么?因为这可以防止每次创建对象时重写每个方法。通过这种方式,您可以为创建的每个对象回收相同的原型。高效的内存和节省编码时间。new
代替Object.create
。如果你习惯了其他的OOP语言,它会更容易记住;最后new
在引擎盖下使用Object.create
。换句话说,类似这样的东西:
编辑
一些额外的信息:
*Object.create vs new。Benchmark here。虽然这个问题是针对Node.js的,但我认为同样的行为是可以预期的。(欢迎更正)
*模拟私有属性的闭包:你可以在这个问题中读到。private/closure属性不属于对象是一个编程事实:它们可由对象方法访问,但不属于对象。当使用继承时,这是一个很大的混乱。此外,只有在构造函数中声明的方法才能访问闭包。在原型中定义的方法不需要。
*在构造函数或prototype属性中定义方法:读取this question,并查看this benchmark
编辑15/04/2016
三年前我在这里提出的观点从性能的Angular 来看仍然是正确的,但我对什么是“推荐方式”的看法在此期间发生了一些变化。工厂函数通常是一个很好的选择,这将是OP的第一种方法。举个例子:
然后就这样做:
在这种情况下,您可以牺牲灵活性(没有
new
耦合,易于与其他“mix-in”组合)和简单性(没有this
混乱,易于对象示例化)来换取一定的速度和内存。一般来说,它们是完全有效的。如果您有性能问题,并且这些问题是由于这种创建对象的方式造成的,请恢复到另一种方法。Object.create
方法也很好,在某种程度上介于new
和工厂函数之间(旁注:新的class
语法是new
+prototype
的语法糖)总结:我推荐的方法是从最简单和最容易的创建对象的方法(工厂函数)开始,然后在遇到性能问题时(在大多数情况下,这是永远不会发生的)转向其他方法。
2023年编辑
自从我写了这个答案后,下了很多雨,它不再相关了。只需使用
class
并担心真实的的问题。8fsztsew2#
在JS中有很多方法可以创建“类”和“对象”。我更喜欢这样:
w51jfk4q3#
注意:如果你更熟悉OOP语法,你也可以使用
class
,它只是在现有的基于原型的方式上的语法糖。4种创建对象方式性能对比-带构造函数(Chrome 61 -https://jsperf.com/create-object-ways)
选项A:使用
return
(最快3x)选项B:使用
{key:value}
(1.5x)选项C:使用
prototype
(1x)<- Base选项D:使用
class
(1.02x)选项A似乎表现最好。请注意,性能提升的部分原因是它避免了使用
new
或object.create
。为了公平起见,这里是另一个没有构造函数和属性的纯方法对象之间的测试。创建纯方法对象的4种方法性能比较(Chrome 61 -https://jsperf.com/create-static-object-ways)
选项A:使用
return
(3.2x)选项B:使用
{key:value}
(最快3.3x)选项C:使用
prototype
(1.8x)选项D:使用
class
(1.9x)选项B略优于选项A。此外,
object.create
造成的瓶颈比new
更多。最佳实践
选项A(使用
return
)在这两种情况下性能最佳。如果你有很多方法和属性,这种方式可能会有点混乱。我更喜欢使用选项A将构造函数和属性划分为单独的对象,使用选项B将方法划分为另一个对象。这种方法确实需要在参数中发送一个额外的
instance
引用,但如果你有多个对象使用相同的属性和构造函数(也可以实现一些OOP继承),这种方法可能很有用。示例: