【问题标题】:Private properties and closures私有财产和关闭
【发布时间】:2013-12-10 22:20:54
【问题描述】:

我想知道如何使用原型对象和闭包上的私有属性来创建 JS 计数器(希望如下所示)。如果有人能告诉我如何做,但也可以发表评论,以便我理解步骤和过程,我将不胜感激。

<!DOCTYPE html>
<html>
<body>
    <button name="button" class="click-tracking">Click Me</button>
    <script>
    var counts = {},
    track  = document.getElementsByClassName('click-tracking');

for (var i = 0, max = track.length; i < max; i++) {
    track[i].addEventListener('click', function() {

        var name = this.name,
            ele  = document.getElementById(name + '-count') || false;


        if (typeof counts[name] === 'undefined') {
            counts[name] = 0;
        }


        if (!ele) {
            var ele    = document.createElement('div');
                ele.id = name + '-count';


            this.parentNode.insertBefore(ele, this.nextSibling);
        }

        ele.innerHTML = counts[name]++;
    });
}
        </script>
</body>

</head>
</html>

【问题讨论】:

  • 我不明白这个问题。你的代码有什么问题(看起来很有效)?
  • 你想要一个原型对象做什么?此功能绝对没有必要 - 您没有任何共享公共属性的多个实例。
  • 我想为按钮制作一个计数器,但我想在原型和闭包上使用私有属性,而不是仅仅使用 js。因此,我只是将代码放入示例中,以说明我希望它的外观。很抱歉造成混乱。
  • 我只是想用我熟悉的东西来进一步了解原型和闭包。
  • 很抱歉,这些概念不适用于这个熟悉的简单脚本。顺便说一句,你从哪里得到的?没有“原型上的私有属性”之类的东西,这在 JavaScript 中是不可能的。

标签: javascript button closures prototype


【解决方案1】:

原型在实例之间共享,并且由于您只能通过闭包模拟私有,因此您不能在原型上拥有特定于实例的私有值。

有关构造函数和原型的介绍,您可以阅读this answer

创建可以启动和停止的计数器的构造函数看起来像这样(我使用_private 命名约定而不是闭包。

var Counter = function(name){
  //instance specific values
  this._intervalid=false;
  this._counter=0;
  this.name=name;
};
Counter.prototype.start=function(){
  //create closure for invoking object
  var me=this;
  this._intervalid=setInterval(function(){
    me._counter++;
    console.log(me.name,me._counter);
  },100);
};
Counter.prototype.stop=function(){
  if(this._intervalid){
    clearInterval(this._intervalid);
  }
};

var c1=new Counter("counter1");
var c2=new Counter("counter2");
setTimeout(function(){c2.start();},200);
c1.start();
setTimeout(function(){c2.stop();c1.stop();},2000);

【讨论】:

    【解决方案2】:

    您可以创建构造函数来创建原型对象。私有属性可以用局部变量来模拟。这里我们创建了一个本地的count 变量,该变量不能在Counter 函数之外进行修改。

    构造函数绑定点击处理程序并创建一个getter方法来返回当前计数。 getCount 和事件处理程序关闭每个实例的计数值。

    function Counter(trackElement) {
        var count = 0;
        this.getCount = function() { return count; }
        trackElement.addEventListener('click', function() {
            count++;
        });
    }
    
    var counters = [],
        track  = document.getElementsByClassName('click-tracking');
    
    for (var i = 0, i < track.length; i++) {
        counters.push( new Counter(track[i]) );
    }
    

    【讨论】:

    • 原型发生了什么?我似乎记得问题中提到过。
    猜你喜欢
    • 2012-10-08
    • 1970-01-01
    • 1970-01-01
    • 2016-11-17
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-21
    相关资源
    最近更新 更多