jasooon
jasooon

Reputation: 11

Javascript Closure: Pratical Closures example in MDN

Since I don't completely understand the functionality of closures in JavaScript. I have some doubt in the example of Practical Closures in MDN.

(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures)

I try to modify the code given by MDN, but it doesn't work. I don't know why.

What the code in this example can do is that by clicking 12, 14 or 16, the font size of the words can change accordingly.

Here are the original source code and links: http://jsfiddle.net/vnkuZ/

HTML:

<p>Some paragraph text</p>
<h1>some heading 1 text</h1>
<h2>some heading 2 text</h2>

<a href="#" id="size-12">12</a>
<a href="#" id="size-14">14</a>
<a href="#" id="size-16">16</a>

CSS:

body {
  font-family: Helvetica, Arial, sans-serif;
  font-size: 12px;
}

h1 {
  font-size: 1.5em;
}
h2 {
  font-size: 1.2em;
}

JavaScript:

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;

I just modified the JavaScript part:

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

<!-- var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16); -->

document.getElementById('size-12').onclick = makeSizer(12);
document.getElementById('size-14').onclick = makeSizer(14);
document.getElementById('size-16').onclick = makeSizer(16);

It doesn't work...

Upvotes: 1

Views: 156

Answers (1)

jfriend00
jfriend00

Reputation: 707966

You left out the important part of makeSizer() which is the return function() {...}. You must have that part and ONLY modify inside that inner function.

It must be like this if it's going to be assigned the way it is:

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

The inner function which that is returned from makeSizer() is critical to how it was used and is what creates the closure that retains the value of size to be used later when the click event fires and is what assigned a function to the onclick handler rather than just executing the function immediately. These are both very important distinctions are are the entire point of the MDN page.

Here's a step by step explanation:

The onclick attribute needs to have a function assigned to it. Your version of makeSizer() doesn't return anything (which means it returns undefined) so when you were doing:

function makeSizer(size) {
    document.body.style.fontSize = size + 'px';
}
document.getElementById('size-12').onclick = makeSizer(12);

it would execute makeSizer(12) immediately and assign the return result from executing that function which would be undefined to the .onclick attribute and thus clicking on it did nothing because there was no function assigned to the onclick attribute.

With your makeSizer() implementation, you could have instead done this:

function makeSizer(size) {
    document.body.style.fontSize = size + 'px';
}
document.getElementById('size-12').onclick = function() {
    makeSizer(12);
};

That would have worked. Here you can clearly see you'd be assigning a function to the onclick attribute so when the click happened, there is a function to call for the click event.

Upvotes: 1

Related Questions