构造函数vs对象文字与raveling模块模式

时间:2016-12-20 07:39:56

标签: javascript design-patterns

我用javascript编写spagetti代码已经有一段时间了。我试图组织我的代码,但我很困惑使用哪一个以及何时使用某种模式。

构造函数模式

function foods(food){
  this.food = food;
  this.eat = function(){
    return 'I"m eating ' + this.food;
  }
}

var eatApple = new foods("apple");
console.log(eatApple.eat()); 

var eatBanana = new foods("banana");
console.log(eatBanana.eat()); 

object literal

var foods = {
  food : null,
  eat : function(){
    return 'I"m eating ' + this.food;
  }
};

foods.food = 'apple';
console.log(foods.eat());

foods.food = 'banana';
console.log(foods.eat());

揭示模块

var foods = function(){
  var defaultFood = "default food";
  function eat(food){
    //this is ugly
    if(food){
      food = food;
    }else{
      food = defaultFood;
    }
    return 'I\"m eating ' + food;
  }

  return {
    eat: eat
  };
}();

var justEating = foods.eat();
var eatingApple = foods.eat('apple');
var eatingBanana = foods.eat('banana');

console.log(justEating);
console.log(eatingApple);
console.log(eatingBanana);

我认为对象文字是最常用的,为什么不是每个人都只使用它? 2016年还有相关的揭秘模块吗?大多数人只会做module.exports。

1 个答案:

答案 0 :(得分:0)

我不推荐使用对象文字模式,因为很难将其用作模板。我不知道揭示模块,但编码风格看起来很丑陋和繁琐。

考虑这个例子,

对象文字:

var Fruit = {
  type: "Banana",
  getType: function(){
    alert("My type is " + this.type);
  }
}

Fruit.type = banana;
Fruit.type = mango;
Fruit.getType(); // displays  My type is Mango

现在,如果您想要添加类似" Mango"的水果类型,您将再次编写整个对象或更改上述对象。换句话说,它的行为不像是类的实例,因此很难使用它。

如果它是构造函数模式,那么它将非常容易。

构造函数模式:

var Fruit = function(type){
  this.type = type
}

Fruit.prototype.getType = function(){
  alert("My type is " + this.type);
}

var banana = new Fruit("Banana");
var mango = new Fruit("Mango");
banana.getType(); // displays  My type is Banana
mango.getType(); // displays  My type is Mango

整个事物就像一个类(模板),并且很容易创建相同的实例。它也很容易继承。

Checkout ES6, the syntax is sweet

更新:

揭示模块模式:

这个使用闭包,如果不小心使用它很容易出错。例如,

var Fruit = function(){
  var type = null;
  var getType = function(){
    return "My type is " + type;
  };

  return {
    type: type,
    getType: getType
  }
}

var newFruit = Fruit();
newFruit.getType(); // My type is null

newFruit.type = "Banana"; 
newFruit.getType(); // My type is null

在这种特殊情况下,即使你改变了类型,函数getType()也不会按预期执行,因为它仍然记得外部函数Fruit()中的变量。此行为是闭包的结果。