如果只有一个对象的实例,我还应该使用构造函数吗?

时间:2016-12-18 21:29:21

标签: javascript

我一直在深入探索JS世界,并且遇到了三种不同的方式来开发网站的前端推车:

具有原型函数的构造函数

var cart = function(){
    this.items = {}
}

cart.prototype.increaseItemQty = function(partNumber){
    if(this.items[partNumber]){
        this.items[partNumber].qty += 1;
    } else {
        this.items[partNumber] = {
            qty : 1
        };
    }
}

cart = new cart();

构造函数中的方法

var cart2 = function(){
    this.items = {};
    this.increaseItemQty = function (partNumber) {
        if(this.items[partNumber]){
            this.items[partNumber].qty += 1;
        } else {
            this.items[partNumber] = {
                qty : 1
            };
        }
    }
}

cart2 = new cart2();

对象方法

var cart3 = {
    items : {},
    increaseItemQty : function(partNumber){
        if(this.items[partNumber]){
            this.items[partNumber].qty += 1;
        } else {
            this.items[partNumber] = {
                qty : 1
            };
        }
    }
};

如果我知道只有一个购物车实例,那么我应该使用Object Method方法吗?有什么理由我还应该使用构造函数吗?

4 个答案:

答案 0 :(得分:3)

是的,有一个(次要)原因你不应该使用构造函数:实例将通过instance.[[Prototype]].constructor保存对构造函数的引用,因此它不会被垃圾收集。它将无用地浪费内存,因为你不会再次实例化它。



var cart = new function(){ /* ... */ };
console.log(cart.constructor); // Won't be garbage-collected




如果您更喜欢功能方法,您仍然可以执行以下操作。这样你也可以拥有私有变量。



var cart = function() {
  // You can add private variables here
  this.items = {};
  this.increaseItemQty = function(partNumber) {
    if(this.items[partNumber]) {
      this.items[partNumber].qty += 1;
    } else {
      this.items[partNumber] = {
        qty : 1
      };
    }
  };
  return this;
}.call({});
cart.increaseItemQty(0);
console.log(cart.items);




答案 1 :(得分:2)

如果您认为需要使用某些默认值初始化 carts 或者在使用整个对象之前执行一些应该强制执行的初始化操作,则应该使用构造函数。

另一方面,也许你错过了Object.create。您不需要构造函数来实现原型链:

var A = {
    doStuff() {
        console.log("I did some stuff");
    }
};

var B = Object.create(A);
B.moreStuff = function() {
   console.log("I did even more stuff");
};

// A new object where its prototype is B
var someB = Object.create(B);
b.doStuff(); // ...from A
b.moreStuff(); // ...from B

答案 2 :(得分:1)

案例1和案例2之间的区别:在案例1中,您将方法分配给cart类或其子类的所有实例,而案例2仅分配给cart的实例。

案例2和案例3之间的区别:在案例3中,您只需使用对象初始化程序表达式创建一个实例,并将一些方法指定为其属性。

现在,如果要回答你的问题,如果你只有一个实例,理论上你就可以像方案3那样添加方法作为其属性。甚至可以编写过程式函数。

但就代码的可扩展性和可重用性而言,最佳实践是通过创建来利用方法。 javascript中的类是具有相同原型的对象集。所以最好是将方法添加为原型对象的属性,如案例1 。如果您只有一个实例 - 对您没有任何区别。但由于cart应该是非常沉重和复杂的类,因此无论何时购物车的要求发生变化,案例1都将是最方便的。

答案 3 :(得分:1)

要创建一个对象,基本上可以使用构造函数'函数创建一个对象。或者只是使用对象符号' {}'在你的情况下,两者都完全相同。

构造函数模式的主要优点是,如果您在创建实例时需要处理参数,将会更有用。

function Car(model) {
   this.model = model;
}

或者如果您需要使用下面的私有变量和方法。

function Car() {
   // private variable
   var modelYear = 1990;
   // private method
   var isEligibleToInsurance = function() {
       return this.modelYear > modelYear;
   };

  this.isLatestModel = function() {
      return isEligibleToInsurance();
  };
}

通过这种方式,您可以拥有一个私有方法,并在公共方法中使用相同的方法。当您使用对象表示法时,您不能在所有公共方法中使用通用的私有方法,并且当您使用' prototype'时,您无法使用构造函数内声明的私有方法

注意:当您为该课程命名时,您可以按照pascal case将其命名为" Car"而不是" car"并使用驼峰大小写创建实例" var car = new Car();"