Closures allow returned inner functions to capture variables defined in outer functions (light definition)
They are useful when used as private variables, or don't want to pollute global namespace.
Here are two examples of some of my previous posts :
// https://github.com/ai/nanoid
//A tiny, secure, URL-friendly, unique string ID generator for JavaScript.
let nanoid=(t=21)=>crypto.getRandomValues(new Uint8Array(t)).reduce(((t,e)=>t+=(e&=63)<36?e.toString(36):e<62?(e-26).toString(36).toUpperCase():e>62?"-":"_"),"");
function Counter () {
let count = 0
function View () {
let uuid = nanoid()
let div = document.createElement("div")
div.innerHTML = `
<h1 id=display-${uuid}>${count}</h1>
<button id=counter-${uuid}>CLICK</button>
`
let target = div.querySelector(`#display-${uuid}`)
let btn = div
.querySelector(`#counter-${uuid}`)
.onclick = () => target.innerText = ++count
return div
}
return View ()
}
[...Array(5)].forEach(() => document.body.append(Counter()))
Here is an updated version, thanks Eckehard
// allow pausing while rotate
function sleep(ms = 0) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// returns an object containing the closure and the refrenced image
function rotateImage (id) {
let angle = 0;
let prevangle = 0
let img = document.getElementById(id);
async function _rotateImg () {
while (angle < prevangle + 90) {
angle += 19;
await sleep(0)
img.style.transform = `rotate(${angle}deg)` ;
}
let rest = angle % 90;
// increment is not a divisor of 90
// we adjust the rotation
if (rest > 0) {
while (rest > 0) {
rest -= 1
await sleep(0)
img.style.transform = `rotate(${--angle}deg)` ;
}
}
img.dataset.angle = angle
prevangle = angle
checkImages()
}
return { rotator: _rotateImg, image:img } ;
}
// we check if all images are in nomal position
function checkImages () {
let aligned = [imagegRotator, imagegRotator2].reduce(
function check (acc,imgrot) {
return (imgrot.image.dataset.angle % 360 === 0) && acc
}
, true);
if (aligned) {
message.innerText = ("We are two cutes American Pit Bull Terrier")
}
else {
message.innerText = ""
}
}
function main () {
// we have to declare those variable as globals
// to attach onclick events
window.imagegRotator = rotateImage("image");
window.imagegRotator2 = rotateImage("image2");
checkImages ()
console.log(Object.keys(imagegRotator));
}
main()
Top comments (1)
Good explanation! Just fiddeling around with global id´s (even if you use uuid´s) is a bit contraproductive in this case. I would prefer to keep all references local, which makes the code much cleaner.
Example