Check out a free preview of the full The Good Parts of JavaScript and the Web course

The "Functions" Lesson is part of the full, The Good Parts of JavaScript and the Web course featured in this preview video. Here's what you'd learn in this lesson:

In JavaScript, functions are very versatile. They can be used as methods, classes, constructors, modules, etc. Doug discusses the behavior and syntax of functions. He also talks about function variables and explains concepts like hoisting.


Transcript from the "Functions" Lesson

>> [MUSIC]

>> Douglas: So Act III, function the ultimate. You've been wondering when are we gonna get to the good parts, right? Because everything's been pretty horrible up until now, right? Hasn't this been kind of tragic? So we're gonna get to some good parts and the good parts in JavaScript all wrap around the function.

Functions are really powerful bits of stuff. In other languages, you'll have methods, classes, constructors, modules. In JavaScript all you need is functions. Functions are so powerful. They can do the work of all of those things and more. They're just serving a universal stuff for building things. We make functions using the function expression or function literal.

It would return a new function object, which could then be invoked. A function expression starts with the word function. It can then take an optional name, which allows you to call the function recursively. It also allows for documenting things like a code and stack traces. You pass it parameters, which are a set of names separated by commas wrapped in parens.

And it takes a body, which is a block wrapped in curly braces. A function expression produces an instance of a function object. And every time that expression gets evaluated you'll get a new function object. Function objects are first class, which means they can be passed as arguments to functions.

They can be returned from functions, they may be assigned a variables, and they may be stored in objects and arrays. This is very different than in languages where functions are sort of the static things, which just kind of exist before the program starts. In JavaScript, the functions run and add things to the environment as they're compiled.

And because functions are objects they inherit from function not prototype. We use the var statement to declare and initialize variables within functions. You don't specify a type in the var statement. It can accept any type. And variables declared anywhere within a function are visible everywhere within the function.

So we don't have block scope with the var statement we only have function scope. So, the var statement is does a really weird thing, it gets split into two parts. The declaration part gets hoisted to the top of the function where the variable gets initialized with undefined. And the initialization part turns into an ordinary assignment statement.

So here we've got var myVar = 0, var myVar = undefined gets hoisted to the top of the function. And at the sight of the original statement, we get an ordinary assignment statement, which does initialization.
>> Douglas: To make things more complicated, JavaScript has a function statement or a function declaration.

Which unfortunately looks exactly like the function expression. It starts with the word function in this case the name is mandatory. You can't leave it out. It takes the same parameters and takes the same body. So it looks exactly like the other one. The function statement is a shorthand for a var statement with a function value.

So function foo expands into var foo = function foo. And that further expands because of hoisting into var foo = undefined and foo = function foo. Both of these now get hoisted to the top of the function.
>> Douglas: It's because of this second hoisting that the language does not allow you to declare a function inside of an if.

Because the assignment of the function variable is going to be pulled out of the f and moved to the top, so that's illegal. Now it turns out most of the JavaScript engines allow you to do it anyway. But because the standard says you can't, they all have different opinions on what it actually means.

I don't recommend doing that.
>> Douglas: So it's really confusing having both function expressions and function statements, which both look exactly the same. So how do you tell them apart? And it depends on where you are. If the first token of a statement is function, then it is a function statement.

If the word function occurs anyplace else, it's a function declaration.
>> Douglas: So we talked this morning about scope, about block scope versus function scope. And block scope is a very common thing, function scope is a very unusual thing, which is unique to JavaScript's var statement.
>> Douglas: So and function scope is sufficient, but function scope looks like block scope.

Or at least the syntax is the same as block scope languages and so you get confusion. So In some languages that have block scope, you can do stupid things like this. Where you can have two loops both using the same variable name as their induction variable. And it works because in those languages, each of these will be in a different scope, and so they won't interfere with each other.

It's extremely unwise but legal. In JavaScript it is also illegal, but it's worse than unwise because there's only one i variable created here. Both loops will be using the same i variable. And so they will interfere with each other really badly and this loop will never correctly perform.

>> Speaker 2: That's because everything gets hoisted into the top.
>> Douglas: It's because both var declarations gets hoisted to the top and there's no check to see if a variable has already been declared. So if there is a second var declaration for the same name good, that's double good. It should be an error, but it's not, because it's not an error can get into trouble.

So because of all of this weirdness I recommend to clear all of your variables at the top of the function. Because that's where they're actually being declared and also declare all of your functions before you call them. All of this hoisting nonsense was created specifically so that you don't have to do that, that you can call a function before it's declared.

But that requires that all this hoisting weirdness be going on and that you understand what the hosting is doing. And I think that's too much to expect of the people reading your program. So instead I think it's much better to say declare the function before you call it.

That's a much easier thing to understand.
>> Speaker 2: But call, you're using the word call where I would call it defining.
>> Douglas: In JavaScript, you can lexically call a function before you can clear it. I can say
>> Speaker 2: I see what you mean.
>> Douglas: I can say foo parent, and then below that I can say function foo.

>> Speaker 2: You don't mean to say var, some function name, and then later on to find a function. I see, nevermind. These two statements, there's not this parallel between these two statements that I'm looking for.
>> Speaker 2: So functions aren't variables.
>> Douglas: No, functions are values that can be stored in variables.

>> Speaker 2: Okay, if they have a name.
>> Douglas: Even anonymous functions can be stored in variables.
>> Speaker 2: Okay.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now