带有requirejs和闭包的私有变量

时间:2014-01-07 12:01:52

标签: javascript requirejs closures

我正在尝试在requirejs中创建一个包含私有变量的类。 (意味着我不希望任何人访问此变量,只能使用私有方法。)

numbox.js

define(function(){
  var counter=0;
  function Numbox(){
  }
  Numbox.prototype = {
    add_and_show:function(){
      counter++; alert(counter);
    }
  }
  return Numbox;
}

如果我创建任何新的Numbox实例并调用该方法,这是不正确的,所有实例将共享相同的计数器如下。

require(['numbox.js'], function(Numbox){
  var box1 = new Numbox();
  var box2 = new Numbox();
  box1.add_and_show(); // alert(1);
  box2.add_and_show(); // alert(2); instead of "1"
}

即使我把counter放在constructer函数下如下,它可以工作,但它没有实现我的目标,因为我希望它是私有的。 (我仍然可以通过box1.counter或box2.counter访问“counter”)

numbox.js

define(function(){
  function Numbox(){
    this.counter =0;
  }
  Numbox.prototype = {
    add_and_show:function(){
      this.counter++; alert(this.counter);
    }
  }
  return Numbox;
}

请建议正确的方法。 THX!

2 个答案:

答案 0 :(得分:2)

你无法拥有一切。 (正如圣人所说,“你会把它放在哪里?”: - /)

在这种情况下,你真正不能拥有的是原型函数可以访问的完全封装数据。正如elclanrs所说,如果你愿意放弃隐私,你就是第二个例子。另一方面,如果隐私比内存更重要,那么你可以这样做:

define(function(){
    function Numbox(){
        var counter = 0;
        this.add_and_show=function(){
            counter++; alert(counter);
        }
    }
    return Numbox;
}

现在counter完全是私密的。但是每个Numbox实例都有自己的add_and_show私有副本。您可以自行决定权衡。但我从未见过任何可以让你实现这两种技术的技术。

答案 1 :(得分:1)

如果你确实需要这个(提示,你可能没有),一种方法是跟踪“私有”范围内的实例和计数器,如下所示:

define(function(){

  var counters = [];
  var instances = [];

  function Numbox() {
    instances.push(this);
    counters.push(0);
  }

  Numbox.prototype = {
    addAndShow: function() {
      var idx = instances.indexOf(this);
      var counter = counters[idx]++;
      return counter;
    }
  };

  return Numbox;
});

var n = new Numbox();

console.log(n.addAndShow()); //=> 0
console.log(n.addAndShow()); //=> 1
console.log(n.addAndShow()); //=> 2

var n2 = new Numbox();

console.log(n2.addAndShow()); //=> 0
console.log(n2.addAndShow()); //=> 1

// More tests

console.log(n.addAndShow()); //=> 3
console.log(n2.addAndShow()); //=> 2