Wasteland Wasteland - 3 years ago 380
Javascript Question

JavaScript - Closures

I'm reading the explanation of closures on Mozilla developer site and am struggling a bit. Please have a look at the following code from Mozilla website. I kind of understand how it works but I'd think that the code below my comments should also work. Why does it not work if one click on 18 and 20?

/* mozilla dev code */
function makeSizer(size) {
return function() {
document.body.style.fontSize = size + 'px';
};
}

var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16);

document.getElementById('size-12').onclick = size12;
document.getElementById('size-14').onclick = size14;
document.getElementById('size-16').onclick = size16;
/* end of mozilla dev example */
/* my code starts */
/* see - no inner function below */

function makeS(size) {
document.body.style.fontSize = size + 'px'
}
/* Let's see if that works */

var size18 = makeS(18);
document.getElementById('size-18').onclick = size18;



/* What about that? */

document.getElementById('size-20').onclick = makeS(20);


Why

CodePen:
http://codepen.io/wasteland/pen/qqoooW

Answer Source

makeS(18) immediately invokes the function and changes the size. What you assign to the onclick event in that case is actually undefined, since that's what the function returns when invoked, as it has no explicit return.

function makeS(size) {
        document.body.style.fontSize = size + 'px'
}

console.log("font size before calling makeS:", document.body.style.fontSize); //it's actually an empty string, hence why it doesn't show up in the output

var size18 = makeS(18);

console.log("font size after calling makeS:", document.body.style.fontSize);

console.log("what is size18?", typeof size18);

By contrast, makeSizer(18) will create a new function that when called, will change the size.

function makeSizer(size) {
  return function() {
      document.body.style.fontSize = size + 'px';
    };
}

console.log("font size before calling makeSizer:", document.body.style.fontSize); //it's actually an empty string, hence why it doesn't show up in the output

var size18Function = makeSizer(18);

console.log("font size after calling makeSizer:", document.body.style.fontSize); //it's still an empty string

console.log("what is size18Function?", typeof size18Function);

//let's call it now
size18Function();

console.log("font size after calling size18Function:", document.body.style.fontSize); //it's still an empty string

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download