Understanding Variables, Arrays, Loops, and Null: The Post-it Note Analogy

What does var actually do, and why doesn't setting myObject = null actually remove the object? These questions tie in to a fundamental concept in coding, relevant whether your language of choice is AS3, JavaScript, or C#, and can be understood using a few common items from the stationery cupboard.


What's a Variable?

Let's start with the basics. Suppose you want to store the age of your friend Bill:

(I'm going to use AS3 for these example, but the basic concepts are the same in JavaScript and C#.

In JavaScript, the syntax is almost the same, but we don't specify that age is a number:

In C# we don't use the var keyword, but we do specify the type of the variable:

Not different enough to be confusing, I hope.)

So what's happening here? Think of it this way:

  • var (or short, in C#) means, "get a fresh Post-it note".
  • ageOfBill means, "write ageOfBill across the top, in pen".
  • = 24 means, "write 24 on the note, in pencil".
Understanding Variables, Arrays, Loops, and Null: The Post-it Note Analogy

What if later we realise that Bill's actually younger than we thought?

This just means we find our ageOfBill note, erase 24, and write 20 on it instead.

Understanding Variables, Arrays, Loops, and Null: The Post-it Note Analogy

We could write var again:

...but this is not good code, because var says, "get a fresh Post-it note". If you do this, the compiler will usually figure out what you mean - i.e. that you want to change what's written on the existing ageOfBill Post-it note rather than actually getting a fresh one - but it will probably complain.

It depends on the language and on your coding environment.

So can we ask the compiler to get a fresh Post-it note and write a label on it in pen, without writing anything on it in pencil? Perhaps we could do this for Bill's friend Marty, whose age we don't know:

Actually (in AS3, at least) this will get a fresh Post-it note, write ageOfMarty across the top, in pen... and then write a default initial value of 0 on there in pencil:

Understanding Variables, Arrays, Loops, and Null: The Post-it Note Analogy

So, in other words, we can't have a Post-it note like this without it taking some value.

Okay - what about if we want to store the age of Bill's best friend Ted, who we know is the same age?

What happens here is, the computer looks at the ageOfBill Post-it, then copies the number written on it in pencil to a fresh Post-it, on which it writes ageOfTed across the top in pen.

Understanding Variables, Arrays, Loops, and Null: The Post-it Note Analogy

This is just a copy, though; if we then change the value of ageOfBill it won't affect ageOfTed:

Understanding Variables, Arrays, Loops, and Null: The Post-it Note Analogy

So! That's all pretty straightforward, and maybe even intuitive. Now let's talk about the first common pain point: arrays.


What's an Array?

Think of an array as a ring binder.

Understanding Variables, Arrays, Loops, and Null: The Post-it Note Analogy

(I was going to say a rolodex...

Understanding Variables, Arrays, Loops, and Null: The Post-it Note Analogy

...but I realised that I had never even seen one in real life.)

Each sheet inside the binder is like one of those Post-it notes, except without the pen-written label across the top. Instead, we refer to each sheet by the name of the binder and the page number of the sheet.

Let's suppose we've got an array of all our friends, in no particular order. Who's on the first page (page #0)?

(trace() just writes the line to the debug output; in JavaScript, you might use console.log() and in C# you might use Console.WriteLine() for the same purpose.)

Understanding Variables, Arrays, Loops, and Null: The Post-it Note Analogy

It's Bill!

So, now, what does the following line do?

It gets a fresh Post-it note (because of the var keyword), writes firstFriend across the top in pen, then copies whatever's written on the first page of the binder onto that note in pencil.

Understanding Variables, Arrays, Loops, and Null: The Post-it Note Analogy

(Remember, String just means a piece of text.)

We can overwrite what's written on any page of the binder, just like with the Post-it notes:

Understanding Variables, Arrays, Loops, and Null: The Post-it Note Analogy

...and of course this doesn't affect the firstFriend Post-it.

The binder is an apt analogy, because - just like with an array - you take take pages out, add new ones, and rearrange them. But remember, individual pages act just like the Post-it notes, except they don't have their own pen labels, just page numbers.

Still pretty straightforward, I hope. So here's an interesting question: what happens when you do the following?

Uh...


You Can't Write That on a Post-it

I've cheated a bit here, because I talked a bunch about arrays without ever explaining how we create one in the first place. So let's tackle that now.

Suppose you type:

...What happens?

Well, as usual, var friends means we get a fresh Post-it note and write friends across the top, in pen:

Understanding Variables, Arrays, Loops, and Null: The Post-it Note Analogy

But what do we write on it in pencil?

It's a trick question: we don't write anything.

See, Array means, "get a new ring binder". And ["Bill", "Marty", "Ted"] means "put three pages in the binder, with these names on it":

Understanding Variables, Arrays, Loops, and Null: The Post-it Note Analogy
You can't see the "Marty" and "Ted" pages, but they're totally there.

And then? It's simple! We stick the friends Post-it note to the cover of the binder:

Understanding Variables, Arrays, Loops, and Null: The Post-it Note Analogy

Now, when we write:

...we know that we have to find the Post-it labelled friends, then look at whatever's written on the first page (page #0) of the binder that it's stuck to.

There are actually very few types of variable where a value gets written onto a Post-it note in pencil. In AS3, the only such types (called "primitives") are:

  • Number
  • String
  • int
  • uint
  • Boolean

For everything else - Object, MovieClip, XML, and so on - we stick the Post-it note onto the item itself.

Understanding Variables, Arrays, Loops, and Null: The Post-it Note Analogy

(The details are a little different in JavaScript and C#, but overall the same idea applies.)

So let's get back to our earlier question. When we type:

...what happens?

Again, we know that var listOfNames means "get a fresh Post-it note and write listOfNames across the top in pen". And now we know that Array means we'll be sticking the Post-it note to something (a binder), rather than writing something on the Post-it in pencil.

Previously, when we've done something similar, we've copied the contents of one Post-it note onto another. So here, should we get a fresh new binder and copy all of the pages from the friends binder into it?

Actually, no! All we do is stick this new listOfNames Post-it note onto the same binder as the friends Post-it note.

Understanding Variables, Arrays, Loops, and Null: The Post-it Note Analogy

Now, friends and listOfNames each refer to the exact same array. So if we write:

...then friends[0] will also be Emmett, because listOfNames[0] and friends[0] refer to the exact same page in the exact same binder! And because that page only contains a String (which is a "primitive" type, remember), then we've just erased whatever was written on that page previously and written Emmett there instead.


So What Does null Mean?

Seen like this, null is quite easy to understand. This statement:

...just means, "remove the friends Post-it note from whatever it's currently stuck to".

Understanding Variables, Arrays, Loops, and Null: The Post-it Note Analogy

The friends Post-it still exists, it's just not stuck to anything. So if you type:

or

...then you'll get an error, because you're trying to reference the first page of the binder that the friends Post-it is stuck to - but it's not stuck to anything!

So, to be clear, setting friends = null doesn't affect the binder at all. You can still access it just fine via listOfNames. And you can even type:

...to go right back to the old situation:

Understanding Variables, Arrays, Loops, and Null: The Post-it Note Analogy

Garbage Collection

Like I said, setting friends = null doesn't affect the binder directly, but it can have an indirect effect.

See, if there are no Post-it notes stuck to the binder at all, then there's no way for anyone to access the binder ever again. It'll just lie around, totally inaccessible. But having all these binders (and other objects) lying around, totally abandoned, is a real waste of space - they're cluttering up the computer memory.

That's where the garbage collector comes in. This is a tool that periodically checks for any "lost" objects, and throws them in the trash - and once they're gone, they're gone for good; if an array is garbage collected then all of its pages are, too.

For most practical purposes, this doesn't affect you at all; objects only get garbage collected if they're lost and unable to be found by your code. If you have a lot of these lying around, then you might notice a slight lag every now and then, when the garbage collector does its job (it takes a little time to actively collect the garbage). The benefit is that this clears up more room (memory) for your app.

(If you want to know more about this topic, read Daniel Sidhion's posts on garbage collection and object pooling.)


Arrays of Objects

Okay, there's one more big concept to grasp - and it's the most complex one yet.

Consider this snippet:

How the heck does that work?

Let's start with what we know. The first three lines are easy; for each one we:

  • Get a fresh binder.
  • Insert a page with the friend's name written on it in pencil.
  • For nsert another page with the friend's age written on it in pencil.
  • Get a fresh Post-it and write the appropriate label across the top in pen.
  • Stick the Post-it to the binder.
Understanding Variables, Arrays, Loops, and Null: The Post-it Note Analogy

As for this line:

...we're going to need some string and some tape.

We can think of that one line as being equivalent to this snippet:

The first line is easy: get a fresh binder and a fresh Post-it note, write allFriends on the Post-it note, and stick it to the binder.

Understanding Variables, Arrays, Loops, and Null: The Post-it Note Analogy

As for the second line:

Remember that I said that each page in a binder is like a Post-it note, except without anything written in pen. If the first page was a Post-it, then we'd simply stick it to the front of the firstFriendDetails binder, right?

Understanding Variables, Arrays, Loops, and Null: The Post-it Note Analogy

...but it can't be both on the front of that binder and inside the other binder. So, instead, we use string:

Understanding Variables, Arrays, Loops, and Null: The Post-it Note Analogy

Same for the other two:

Understanding Variables, Arrays, Loops, and Null: The Post-it Note Analogy

So when we want to know what allFriends[2] refers to, we just open the allFriends binder to that page and follow the string - which, of course, leads to the thirdFriendDetails binder.

Similarly, for allFriends[1][0], we first figure out which binder allFriends[1] refers to, and then we look at the first page of that binder... so allFriends[1][0] is Marty!


Loops

Now put all that information together, and bear it in mind when reading this snippet:

What if we modify the value of currentFriend inside the loop?

What if the array contains non-primitive objects (MovieClips, images, arrays, 3D objects, whatever)?

Finally, what if the array contains other arrays, which themselves contain primitives?

What do you think the value of friends[3][0] will be after that?


Other Bits and Pieces

Here are a few other important notes you should know:

Objects

In AS3 and JavaScript, Objects are like Arrays except each page is referred to by a label rather than by its page number. So you can type:

...and this is kind of like getting a fresh binder, sticking a detailsOfBill Post-it on the front, and filling it with three pages. The first page has the label title written across the top in pen and the word Esquire written on it in pencil; the second page has the label bandName in pen and Wyld Stallyns in pencil. The third page has the label allNames but has nothing written on it in pencil; instead, a string attaches it to another, regular binder, whose pages are not labelled: the first page says Bill, the second says S., and the third says Preston, all in pencil.

(To make things even more confusing, arrays are technically a special form of Object. And if you think that's bad, functions can be seen as a type of Object, too! But that's a topic for a future article...)

More on Garbage Collection

I said that objects are garbage collected if they don't have any Post-it notes stuck to them, but this is an oversimplification. If one page of a binder points to an object via string (i.e. if myArray[0] = myObject or similar), then that object won't be garbage collected. Same goes for if a page of a binder points to another binder (array), or if the page of an object binder points to another object binder... and so on. It even applies if the only way to access the object is through a Post-it stuck to a binder which has one page that's tied to another binder, as many layers deep as you want to go.

Basically, the garbage collector only collects an item if it can't be reached through any other variable.

This explains why objects that are on the screen usually can't be object collected. In AS3, if a MovieClip or other type of DisplayObject is in the display list, then it's automatically added to what is essentially a hidden array of display objects (which you can access via getChildAt()). Similar structures exist in JavaScript and C#. So if a graphic is on the screen, and you remove all references to it from variables, arrays, and objects, it still won't be garbage collected until you remove it from the display list.


Any Questions?

I hope this helps to clear things up. It's certainly a confusing concept when you first come across it: some variables actually contain a value, while others just contain a reference to an object. Don't worry if you're not 100% sure exactly what's going on; it'll make a lot more sense after a bit of practice (and a few mistakes!).

However, if you have any specific questions about it, just stick a comment below and I'll do my best to answer.

Thanks for reading!

Tags:

Comments

Related Articles