Javascript Closure vs Javascript OO

时间:2015-04-09 12:55:47

标签: javascript oop closures

我正在阅读Closures,它有以下闭包的示例。

var makeCounter = function() {
var privateCounter = 0;
  function changeBy(val) 
     {
       privateCounter += val;
     }
  return 
     {
       increment: function() 
     {
       changeBy(1);
     },
  decrement: function() 
     {
       changeBy(-1);
     },
  value: function() 
     {
       return privateCounter;
     }
   }
};

var counter1 = makeCounter();
var counter2 = makeCounter();
alert(counter1.value()); /* Alerts 0 */
counter1.increment();
counter1.increment();
alert(counter1.value()); /* Alerts 2 */
counter1.decrement();
alert(counter1.value()); /* Alerts 1 */
alert(counter2.value()); /* Alerts 0 */

我想知道这个闭包和产生相同结果的下面代码之间的区别和优点/缺点是什么。  

var makeCounter = function() {
var privateCounter = 0;
  function changeBy(val) 
      {
        privateCounter += val;
      };
   this.increment= function() 
     {
       changeBy(1);
     };
   this.decrement= function()
     {
       changeBy(-1);
     };
   this.value= function() 
     {
       return privateCounter;
     };
  };

var counter1 = new makeCounter();
var counter2 = new makeCounter();
alert(counter1.value()); /* Alerts 0 */
counter1.increment();
counter1.increment();
alert(counter1.value()); /* Alerts 2 */
counter1.decrement();
alert(counter1.value()); /* Alerts 1 */
alert(counter2.value()); /* Alerts 0 */

1 个答案:

答案 0 :(得分:1)

你的第二个版本也使用了闭包,在这方面几乎没有区别。

重要的区别是你的第一个makeCounter是一个返回对象文字的工厂(继承自Object.prototype),而你的第二个makeCounter是一个构造函数(需要是调用new}确实返回从makeCounter.prototype继承的实例。您可以通过在原型上移动方法来gain some advantages

function Counter() {
    var privateCounter = 0;
    this.changeBy = function changeBy(val) {
        privateCounter += val;
    };
    this.value = function() {
        return privateCounter;
    };
}
Counter.prototype.increment = function() {
    this.changeBy(1);
};
Counter.prototype.decrement = function() {
    this.changeBy(-1);
};

您可以避免闭包(特权方法)并仅使用原型方法:

function Counter() {
    this.counter = 0; // no more private
}
Counter.prototype.valueOf = function() {
    return this.ounter;
};
Counter.prototype.increment = function() {
    this.counter += 1;
};
Counter.prototype.decrement = function() {
    this.counter -= 1;
};