JavaScript Tutorial, Part 2 - Functions and Closures

| Comments

As famous Douglas Crockford (JavaScript guru) noticed functions in JavaScript are the best thing in JavaScript language. In the beginning of your JavaScript journey you will be most likely using functions not to repeat the same code over and over again - so basically to encapsulate a behavior. For example:

Multiplying function
1
2
3
var multiply = function(a, b) {
        return a*b;
    }

A few things to notice here:

  • Function multiply does not have a name, such function is called anonymous. However it can be invoked, because we have a handle to it - variable multiply
  • Function can be assigned to a variable, just like any of the objects in JavaScript
  • There is no type declaration for the parameters a and b. What is more - there is no type checking when you’re invoking the function. Of course - depending on the body of the method (everything between curly brackets) it might or might not work depending on the type of the parameter passed
  • If during function invocation you pass less parameters than it is stated in the definition, like so:
Multiplying function
1
multiply(1);

it’s not going to end with an error. Parameter b will be assigned value of undefined and whole result will also be undefined.

  • If you pass more parameters, any redundant (every parameter but first - assigned to a and second, assigned to b) ones will simply be ignored
  • If function does not return any value, returned value will be undefined
  • Besides using named arguments (a and b in this example), inside of your function you can always use two additional ones - ‘this’ (depending on the context it might take different values, we will discuss this further in the tutorial) and ‘arguments’ - which is an array containing all of the parameters passed to the function during invocation. This means we could read the values of all of the parameters, even if someone would invoke our multiply function like so:
Invoking the function with plethora of parameters
1
multiply(1, 2, 3, 4);

you still would be able to get hold on of this value, like so:

Invoking the function with plethora of parameters
1
2
3
4
5
6
var multiply = function(a, b) {
        arguments[0]; //equals 1
        arguments[1]; //equals 2
        arguments[2]; //equals 3
        arguments[3]; //equals 4
    };

Of course function multiply does not look like it would save a lot of effort. In fact, it would be much easier to simply write

1
5*6

rather than

1
multiply(5, 6)

So for a little more useful example:

Function calculating n to the power of k
1
2
3
4
5
6
7
8
9
10
11
12
var power = function(n, k) {
  var answer = 1;
  for(var i=1; i<=k; i++) {
      answer *= n;
}
    return answer;
};

alert(power(1, 5));
alert(power(2, 5));
alert(power(3, 3));
alert(power(4, 3));

The this keyword

As I’ve already mentioned in this post, this might mean different things, depending on the context (who ‘owns’ given function) and so:

  • this may refer to Window object, when we define and call function like this:
When *this* means Window
1
2
3
4
5
var f = function() {
  alert(this);
    };

f(); // returns object Window
  • this may refer to the ‘parent’ object where function is defined, take a look at the next example, with object initialization:
When *this* means current object
1
2
3
4
5
6
7
8
9
var myCar = {
  model: "Porshe",
  noise: "wroooom",
  makeNoise: function () {
      console.log(this.model + ' makes ' + this.noise);
  }    
};

myCar.makeNoise(); // prints 'Porshe makes wroooom'
  • this can change its context when we use bind method, like so:
Changing meaning of *this* by using *bind*
1
2
3
4
5
6
7
8
9
var myObject = {
    myFunction: function() {
    console.log(this);
        }
};
myObject.myFunction(); //will print Object to the console

var bound = myObject.myFunction.bind(this);
bound(); //now it will print Window to the console

Last topic I wanted to cover in this post is a feature called closures. There are multiple posts, StackOverflow questions, books, etc… covering the topic, however those are coming from a different angles and it’s hard to get a straight answer. However, concept of closures is one of the cornerstones of JavaScript as a language (together with functions and objects). The simplest example of the closure would be the following code:

The simplest closure example in the world
1
2
3
4
5
6
7
8
var outerSpace = "I'm in the outmost scope!";

var functionUsingClosure = function() {
    var innerScope = "I'm inside of the scope of the function";
    console.log("I can see both: " + outerSpace + " and " + innerScope);
}

functionUsingClosure();

If your thought after seeing this code was “Huh? What the hell, this isn’t very impressive” - well, in this case I’m not impressed too, as it seems obvious to me - outerspace was defined on the global (Window object) level - it is not surprising it could be accessed from the scope of the function functionUsingClosure. But the fact this example representes a clousre in action means you’ve most likely already been using closures, you just didn’t know you were.

To end on the high note, let’s take a look at a little more impressive example of how closures work in JavaScript. Consider the following code:

More sophisticated closure example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var globalValue = 'global value';
var letsSaveGoodForLater;

function outerFunction() {
    var functionScopeDeclared = 'inner value (declared in function\'s lexical scope)';

    function innerFunction() {
        console.log(globalValue);
        console.log(functionScopeDeclared);
        console.log(tooLateMate);
    }
    letsSaveGoodForLater = innerFunction;
}
var tooLateMate = "A little bit too late, mate!? But NO!"

outerFunction();
letsSaveGoodForLater();

Let’s take a moment, let this code sink… Now - what do you think will happen after this code runs? Let me dissect this code for you - first function that is executed is outerFunction and there’s nothing surprising here. functionScopeDeclared will get a string value assigned, innerFunction function will be declared and defined and then assigned to a letsSaveGoodForLater variable, declared in the global scope. So - no magic at all. What is interesting however - is the answer to question - what will happen when letsSaveGoodForLater(); is executed?

Without knowing the answer my answer would be the following:

  • since innerFunction have been assigned to a global variable, it will be visible, so invoking letsSaveGoodForLater(); will execute (rather then throwing exception or giving an error message)
  • console.log(globalValue); will log ‘global value’ to the console as this was a global variable
  • console.log(functionScopeDeclared); I would be on the fence here, but gravitating towards undefined being logged to the console. When I’m calling letsSaveGoodForLater(); I only have a referrence to innerFunction dangling somewhere in the air, but how the hell would JavaScript know about the assignment in the outer scope?
  • console.log(tooLateMate); This one would NOT work for sure. How could it?

I obviously know the answers at this point, in case you were thinking in similar manner as I did - I’ve posted my gut feelings here, so you wouldn’t feel like you’re the only stupid person in the world, there’s really plenty of us. Because as it turns out, the output of this program actually is:

Output of the more sophisticated closure example
1
2
3
global value
inner value (declared in function's lexical scope)
A little bit too late, mate!? But NO!

Turns out, when function is invoked it runs in the context of the variables with values assigned at the point of the declaration of the function. And this is the beauty of closures.

Next time we will focus on the JavaScript libraries and IDEs (the tooling) as well as the setup (developer machine) I’ve been using when working on the code for this post.

Comments