简体   繁体   English

私有财产和封闭

[英]Private properties and closures

I am wondering how to create JS counter (desired look below) using private properties on a prototype obeject and a closure. 我想知道如何在原型对象和闭包上使用私有属性创建JS计数器(如下所示)。 If someone could show me how but also comment it so I can understand the steps and process, I would really appreciate it. 如果有人可以告诉我如何做但也可以发表评论,以便我能理解步骤和过程,我将不胜感激。

<!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>

Prototype is shared among instances and since you can only simulate privates through closures you can't have instance specific private values on the prototype. 原型在实例之间共享,并且由于您只能通过闭包模拟私有,因此原型上没有实例特定的私有值。

For an introduction to constructor functions and prototype you can read this answer . 有关构造函数和原型的介绍,您可以阅读此答案

A constructor function creating a counter that can start and stop can look like this (I am using _private naming convention instead of closures. 创建一个可以启动和停止的计数器的构造函数看起来像这样(我使用_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);

You can create a constructor function to create prototype objects. 您可以创建一个构造函数来创建原型对象。 Private properties can be simulated with local variables. 可以使用局部变量来模拟私有属性。 Here we create a local count variable that can't be modified outside of the Counter function. 在这里,我们创建了一个本地count变量,该变量不能在Counter函数之外进行修改。

The constructor binds the click handler and creates a getter method to return the current count. 构造函数绑定click处理程序并创建一个getter方法以返回当前计数。 The getCount and event handler close over the count value for each instance. 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]) );
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM