Create private variables in JavaScript using closures

April 23rd, 2012

When you’re coming from other programming languages to JavaScript one of the things you can find frustrating is the lack of private variables. I know, coming from ActionScript to JavaScript, I was finding myself accidentally overwriting a variable and breaking my code. I’m not going to explain closures because other people have done a far better job than I would. But I’m going to show an example how you can emulate a private variable and compare it to an example where Why do you want to learn about this? Because closures can be really powerful and they’re one of those things in JavaScript that take a while to wrap your head around. This is one of those things that I didn’t really get a first, but I kept reading and reading and finally it clicked.

Now some code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function Pizza() {
    var slices = 0;
    this.cutSlice = function() {
        slices++;
    };
    this.getSlices = function() {
        return slices;
    }
}

var pizza = new Pizza();
pizza.cutSlice(); // increases slices by 1
console.log('pizza.getSlices(): ' + pizza.getSlices()); // logs 1
console.log('pizza.slices: ' + pizza.slices); // logs undefined

I’ve based this off an example by John Resig, but he used ninjas instead of pizza. We have a function called Pizza. Inside PIzza, we declare a variable called slices and set it to zero. Next, we create a method and assign it to this.cutSlices which is like saying Pizza.slices. cutSlices allows us to increase slices by one. And then we create method called getSlices that returns slices. Why do we need that? Well, if you take a look at the next four lines of code, you’ll be able to see what’s happening here. We create a variable called pizza and use it to create a new instance of Pizza. Next we called pizza.cutSlice which increase slices by one. When we console.log pizza.getSlices(), we get one. But if we log pizza.slices, we get undefined. Why? Because we declared slices as a variable, we don’t have access to it unless we create methods like getSlices using the this keyword to give us access to it.

Ok, that’s kinda cool but what’s the point of it? Well, let’s look at another example that I think will help make it clearer.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function Pie() {
    this.pieces = 0;
    this.cutPiece = function() {
        this.pieces++;
    };
    this.getPiece = function() {
        return this.pieces;
    };
}

var pie = new Pie();
pie.cutPiece(); // increases pieces by 1
console.log('Pie.getPiece(): ' + pie.getPiece()); // logs 1
console.log('Pie.pieces: ' + pie.pieces); // logs 1
pie.pieces = 'I like pie!';
console.log('Pie.pieces: ' + pie.pieces); // log ‘I like pie!’

Now we have a function called Pie, which is pretty much the same thing as our Pizza function, except for one difference, instead of var pieces = 0, we have this.pieces = 0. If you look at the lines of code that come after our function, you’ll see the real difference. When we logged pizza.slices, we got undefined, but if we log pie.slices, we get 1 because we have access to that variable. And if you take a look at the last two lines, you’ll see why that can be an issue. We set pie.slices equal to ‘I like pie!’ and when we log it out, we see that it worked. Now if this was a real program, it would be broken because ‘I like pie!’ is unfortunately not a number and we can’t increase it by 1.

So there we go, if you don’t want the variable to be accessible from outside of the function you write your function like the first example. We can also make private methods this way, but that’s another blog post, I think.

One Response to Create private variables in JavaScript using closures

Leave a Reply

Your email address will not be published. Required fields are marked *