【问题标题】:creating an object with a Constructor vs a Closure使用构造函数与闭包创建对象
【发布时间】:2017-09-20 21:45:50
【问题描述】:

问题:下面两个示例的结果对象obj 有什么不同吗?

闭包示例:

var myClosure = function(paramId) {
  return {
    Id : paramId,
    getId : function() {console.log(this.Id)},
    setId : function(sId) {this.Id = sId}
  };
}
var obj = myClosure(2);
obj.getId();//outputs 2
obj.setId(5);
obj.getId();//outputs 5

构造函数示例:

var MyConstr = function(Id) 
{
  this.Id = Id;
  this.getId = function() { console.log(this.Id)};
  this.setId = function(sId) {this.Id = sId};
}
var obj = new MyConstr(2);
obj.getId();//outputs 2
obj.setId(5);
obj.getId();//outputs 5

我知道使用构造函数创建对象是最佳实践,因为这是它的基本目的,并且不会让未来的代码读者感到困惑。我在这里提问的目的是出于好奇。最终结果有什么不同吗?是对象,还是内存使用,还是其他什么?

【问题讨论】:

    标签: javascript object constructor closures


    【解决方案1】:

    两个对象都有相同的属性和方法。然而,用new MyConstr 构造的那个将有它的 [[proto]] 引用 MyConstr.prototype,允许它继承方法和属性。

    您没有使用这些功能,因此在您的情况下没有区别,但您实际上应该在原型上定义 setIdgetId,这将节省内存(不再复制每个实例上的方法)和一点时间(构造函数会做更少的工作)。

    此外,构造实例将允许您使用instanceof 运算符。

    【讨论】:

      【解决方案2】:

      在这个例子中没有区别,但你可以在现实世界的应用程序中使用不同的用法。

      闭包示例通常用于 [The Module Pattern][1] 或 [The Revealing Module Pattern][2]。

      构造函数示例通常用于[构造函数模式][3]和[原型模式][4]模式。

      在你的情况下,我建议使用原型模式,因为目前你正在向每个创建的新对象添加 getIdsetId 函数,而你可以节省一些添加到原型的内存。

      您还应该考虑使用 JavaScript getter 和 setter 代替 getIdsetId

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-22
        • 2021-09-23
        • 2016-07-01
        • 2012-02-05
        • 1970-01-01
        相关资源
        最近更新 更多