0

I am wondering how to create JS counter (desired look below) using private properties on a prototype obeject and a closure. 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>
Matthieu
  • 2,736
  • 4
  • 57
  • 87
  • 1
    I don't get the question. What problems do you have with your code (which seems to be quite working)? – Bergi Dec 10 '13 at 22:47
  • What would you want a prototype object for? It is absolutely unnecessary for this functionality - you do not have multiple instances of anything that share common properties. – Bergi Dec 10 '13 at 22:48
  • I want to make a counter for a button but instead of just using js I want to use private properties on a prototype and a closure. So I just put that code in for an example of what I want it to look like. Sorry for the confusion. – user3088804 Dec 10 '13 at 22:50
  • I just wanted to use something I am familiar with to get a further understanding of prototypes and closures. – user3088804 Dec 10 '13 at 22:52
  • I'm sorry to say that these concepts are not applicable on this familiar, simple script. Btw, where did you get that from? There is no such thing as "private properties on a prototype", that is impossible in JavaScript. – Bergi Dec 10 '13 at 22:59
  • I have just been reading up on prototypes and closures and obviously my understanding of them is pretty poor. I thought I would be able to apply to a counter on a button, apparently not... Sorry! – user3088804 Dec 10 '13 at 23:09

2 Answers2

0

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.

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);
Community
  • 1
  • 1
HMR
  • 37,593
  • 24
  • 91
  • 160
0

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.

The constructor binds the "click" handler and creates a getter method to return the current count.
Both the getCount and the event-handler close over the count value, for each instance, thanks to Js closures.

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]) );
}
Kamafeather
  • 8,663
  • 14
  • 69
  • 99
Jason Harwig
  • 43,743
  • 5
  • 43
  • 44
  • What happened to the prototype? I seem to recall it's mentioned in the question. – HMR Dec 11 '13 at 00:26