JavaScript Fundamentals: Functions

JavaScript Fundamentals: FunctionsIn JavaScript, functions are an integral part of development. They are what contain all of our amazing functionality (hence the name function) and run it whenever we deem worthy. With functions we can make code nonlinear, more organized, and easier to understand. We can also do some crazy stuff with functional programming.

Defining A Function

Before we can use a function, we need to create one, right? Well, technically there are plenty of built-in functions that we can start using right away, but it's just not right to get out of order. So, let's define a function.

There are two syntaxes that can be used to declare functions: the regular function declaration and assigning a function expression to a variable/property. Take a look.

// regular declaration
function foo() {
    // body of the function. Do Stuff Here!
};

// assign expression to variable
var foo = function() {
    // body of the function. Do Stuff Here!
};

For the most part, they achieve the exact same results. The biggest difference relates to variable lifting in a pretty awesome way. Dustin Diaz explains this difference in function declarations. I prefer to stick with the second syntax, regardless of what double D says because I like having the name of the function out front where you can see and because I feel like it's wrong to treat functions differently from everyone else. Plus, that's the syntax you need to use if you want to assign a function as a property of an object. Speaking of objects…

Functions are Objects

What? No they're not, they're functions! Well, yea, but functions are objects, too. Mind Blown Well, it's not blown anymore for me, but it was when I first found this out. Functions can have properties of their own assigned to them, and in fact, they automatically have some as soon as they're created. We'll talk about a few of those a bit later. For now, just check out this perfectly valid JavaScript.

var foo = function() {
    // body of the function. Do Stuff Here!
};

foo.awesomeProperty = "AWESOME";

Sadly, though, we can't assign a beautiful object literal to a function because it would override the function itself. You can, however, still assign an object literal to one of the properties of the function. I'm sure you could have figured that out on your own, though.

Calling a Function

Now that we have some functions, let's use them! You'd think that calling a function would be the simple part, right? Well, there are actually so many ways to call a function that it's probably the most difficult part to learn, unless you're lazy and just use the normal way (which is possible, but can hinder you in more advanced code).

Normal

Let's start with the normal way of calling a function. All you need is to add some parentheses after the name of the function, and possibly add some arguments inside those parentheses.

var foo = function( arg1, arg2, arg3 ) {
    // body of the function. Do Stuff Here!
};

foo();
// or
foo(1, 2, 3);

There's something that is really awesome about JavaScript function calls that I thought sucked at first when I started using JavaScript after I came from a Java background. You can call a function with any number of arguments and not get an error! This is really awesome because it allows you to create functions with "optional" parameters and do something completely different depending on the number of the arguments sent in. jQuery does this a lot with getters and setters. The annoying part is that you might have to check to make sure that people are sending in the right number and right types of arguments. However, if you document your code well enough, you can just claim that it's their problem if they use the wrong arguments and the errors will inform them.

There is another cool thing about this too. You don't need to define any parameters in your function declaration. Instead, all of the arguments can be can be accessed via arguments within the function. Take a look.

var foo = function() {
    console.log(arguments);
};

foo();          // (nothing to output)
// or
foo(1, 2, 3);   // [1,2,3]

arguments is an array-like structure. In reality it is a special type of object that acts like an array in many cases, but has its own functionality and often won't have some functionality that an array does. So if you want it to be an array, use slice to convert it to an array.

var foo = function() {
    var args = Array.prototype.slice.call(arguments);
};

If you're not sure what exactly is going on here, you'll figure it out soon in a section below.

Using new For Constructors

In last week's post, I wrote about JavaScript objects. I talked about how you can write a function and then use new on it to make a new object with it. Well, this is just another way of calling a function. I won't bother going into any more detail here since I just talked about it last week. I do, however, want to mention that prototype is a property of a function like we talked about earlier and which you will see in that post.

call and apply

These two functions happen to be properties of every function. They can be used to call a function with a different context. The context is what controls the meaning of the this keyword and being able to dynamically control the context can be pretty darn useful, especially in a callback situation.

var foo = function() {
    console.log(this.location);
};
var someObject = {
    location: "here"
};

// by default `this` refers to the window, so this will log the current URL
foo();

// here we set the context to `someObject`, so it will log "here"
foo.call(someObject);

This can allow you to essentially use any function as if it was part of any object even though it's defined in a completely separate manner. In the above example, we only saw call used. In that example, using apply would have yielded the exact same result. The only difference between call and apply is the way they send arguments into the function that they are calling. Another code sample might explain this better than just words, so I'll show you one first.

var foo = function(arg1, arg2) {
    console.log(arg1);
    console.log(arg2);
};

var bar = function(arg1, arg2) {
    foo.call(this, arg1, arg2);
    foo.apply(this, [arg1, arg2]);
    foo.apply(this, arguments);
};

bar(1, 2);

The foo function just logs each of its two arguments. Nothing special. The bar function, however, calls foo in three different ways to demonstrate call and apply. For both call and apply, the first argument is the context, which in the case of this example doesn't really matter, so I just threw something in there. The difference between the two functions shows up after the first argument. For call, you supply an arbitrary number of arguments, each of which gets passed in to the function being called as individual arguments. On the other hand, apply takes only one more argument which must be an array or array-like structure (such as arguments, like I demonstrated in the example). Each element of the array is then sent into the function being called as individual arguments.

Calling Parent/Super Functions

Now that we understand call and apply, we can use it for something cool (other than converting arguments into an array as I showed earlier). We're going to use them to call super functions on parent classes. Take a look:

// Define a class with a single function
var Foo = function() {
    // ...
};
Foo.prototype.someFunc = function() {
    // ...
};

// A second class
var Bar = function() {
    // ...
};
// Inherits from Foo
Bar.prototype = new Foo();
// Override `someFunc` in the child class
Bar.prototype.someFunc = function() {
    // ...
    // We still want to call the parent `someFunc`, but it needs to be called as if it's part of this object
    Foo.prototype.someFunc.apply(this, arguments);
}

That's a really long and annoying way to say super(), but right now we'll have to deal with it. At least you know that you can still do it in JavaScript. In ECMAScript.next, this should all change, though, with the introduction of classes. Obviously, there won't be any support in older browsers though, so it'll be a while before it can obtain mainstream use.

Functional programming

I'm not too familiar with functional programming but you can do some things in really strange and amazing ways with a functional mindset. If you want to see a tidbit of functional programming, you can check out this post on DailyJS. I won't get into that stuff myself because I'm not very good at it and there are far better resources for it available around the web.

Conclusion

That wraps up everything I wanted to mention about functions. It's not exactly a short tutorial, but that's just because JavaScript functions are so flexible and awesome. I hope everyone learned something useful. God bless and happy coding.

About the Author

Author: Joe Zim

Joe Zim

Joe Zimmerman has been doing web development ever since he found an HTML book on his dad's shelf when he was 12. Since then, JavaScript has grown in popularity and he has become passionate about it. He also loves to teach others though his blog and other popular blogs. When he's not writing code, he's spending time with his wife and children and leading them in God's Word.


  • http://www.facebook.com/abdulbri Abdul Bari

    i agree with you 100% sure
    http://yourjavascript.com/uploaded/

  • MATTH

    THANKS, GREAT

  • tech dev

    Excellent.. love ur blog. I’m new to advaced Js. your explanation is very clear. Keep Posted. Thanks