DEV Community

artydev
artydev

Posted on

Closure in Javascript - Revisiting Counter Example

In my precedent post I presented an example which was not optimal.

A nice suggestion from Eckehard leaded me to the new version, which is more better as it does not create 'hidden global variables' when using "id's"...

The idea is to not use any external libraries.

ClosureRevisited

function Counter () {
  let count = 0
  let eltCreate = (tag) => document.createElement(tag)
  function View () {
    let alltags = ["div", "h3", "button", "button"]
    let [div, h3, btninc, btndec] = allElts = alltags.map(eltCreate)
    let incby = (incer) => () => h3.innerText = +h3.innerText + incer
    allElts.slice(1).forEach(child => div.append(child))
    h3.innerText = count
    btninc.innerText = "INC"; btninc.onclick = incby(1) 
    btndec.innerText = "DEC"; btndec.onclick = incby(-1)
    return div
  }
  return View ()
}
[...Array(5)].forEach(() => document.body.append(Counter()))  

Enter fullscreen mode Exit fullscreen mode

Top comments (2)

Collapse
 
efpage profile image
Eckehard • Edited

We need to notice that the usage of the HTML DOM API is quite cumbersome. Libraries like VanJS or DML just make the usage more convenient.

If you do not need the advanced features, you can implement the core functionality of the VanJS tag-fúnction with a few lines of code. This may make the code much more readable:

tags = new Proxy({}, {
    get: (tag, name) => {
        return (...args) => {
            let el = document.createElement(name)
            args.map(cl => {
                el.appendChild(typeof (cl) === 'string' ? cl = document.createTextNode(cl):cl)
            })
            return el
        }
    }
})

const { div, h1, button } = tags
Enter fullscreen mode Exit fullscreen mode

Now, you can write the code like this:

function Counter() {
    let count = 0
    function View() {
        let h = h1(`${count}`)
        let b = button("CLICK")
        b.onclick = () => h.innerText = ++count
        return div(h, b)
    }
    return View()
}
for (let i = 0; i < 5; i++) document.body.append(Counter())
Enter fullscreen mode Exit fullscreen mode

Hiere is the working example

Collapse
 
artydev profile image
artydev

Great Eckehard , thank you
"Bare" Javascript developpers will appreciate it :-)