What are function declarations and function expressions?
Basically you can define functions with the function
keyword at least in two ways:
with a Function declaration which starts with the function
keyword, then the name of the function, then the arguments ()
, and finally the statements{}
; Also as a Function expression which can be stored in a variable, a constant or passed through a function argument, the syntax is quite similar to a function declaration, however, a function expression can be anonymous or be named.
Here's an example of a function declaration:
function toggleSwitch(/*arguments*/){
// statements
}
An anonymous function expression:
const toggleSwitch = function(/*arguments*/){
// statements
}
A named function expression:
const toggleSwitch = function switch(/*arguments*/){
// statements
}
You could call all of those functions in the same way, with toggleSwitch()
. So... what's the difference? Can I just use the one that looks prettier? Although it might seems like that, there are actual differences in the way they operate in your code, once you know them is easier to know which to use. Let's dig into it!
Differences between each type of function
Hoisting
Function declarations are available in it's scope from up to down in your code, but a function expression can't be called unless it has already been declared. This means that you can refer to a function declaration even before it has been declared, but not in a function expression. For example:
This one works and the content is logged:
callMeMaybe();
function callMeMaybe(){
console.log("here's my number ๐");
}
This one would throw an error:
callMeMaybe();
// ReferenceError: Cannot access 'callMeMaybe' before initialization
const callMeMaybe = function(){
console.log("Where you think you're going, baby?");
}
// Credit: Carly Rae Jepsen
So if for some reason you need to have access to functions on your code before they've been declared (perhaps to avoid obfuscation of other core functions, or to improve understanding of your code to others), then knowing this becomes handy.
With const
and let
variables you can create block-scoped functions easily
constants and let variables are block-scoped. constants can only be defined once, and let variables even though they can be redefined, they can't be redefined twice with the let
declaration unlike var
statements. Same happens if you use them to define functions. For example:
This one throws a SyntaxError cause you can't have two constants with the same name:
const hello = function(){
console.log("Hello");
}
// SyntaxError: Identifier 'hello' has already been declared
const hello = function(){
console.log("is it me you're looking for?");
}
hello();
// Credit: Lionel Richie
But you can redefine a Function Declaration:
function hello(){
console.log("Hello, it's me");
}
function hello(){
console.log("Hello from the other siiide!");
}
hello();
// logs: "Hello from the other siiide!"
// Credit: Adele
This is useful if you need to block the scope of your functions to avoid their overriding from other sources and get unexpected behaviors. Also this can make debugging easier.
Other things to take in account
- With variables you can make an object of functions (or methods) using the object definition syntax (
{}
), which could lead to more organized code. You could also add methods to a function declaration like thismyFunction.someMethod = ...
, however this was more of a consideration back in the old days, nowadays you could use classes which provide a nicer syntax. Still... there are notable differences I would say. - Since function expressions can be anonymous, this might lead to confusion when that function has an error, but if you name them you can get more specificity in a stack trace. However this could become more obvious when you define a function expression outside of a variable, like in a promise chain.
Which approach should I use?
As many things in life, it depends, each project is different and there are tons of ways to achieve the same thing.
In my personal opinion, I would generally use function declarations cause I think they provide an easier readability. Having the word "function" at the start of a line makes it easier to know that you are defining a function than having "const" or "let" at the start of a line, it's also nice to know I can use them anywhere I want in their current scope. But in general I would rather use function expressions inside function declarations cause inside a function I would normally define variables to complement what the function actually does. But again, it depends, how do you think it best suits your needs?
At the end of the day I would say it depends a lot on you, the people and the project you are working on. So hopefully this article has given you useful insights about JavaScript functions.
Some useful references that were used for this article:
- Go Make Things | Function expressions vs. function declarations revisisted
- MDN Web Docs | Functions
- MDN Web Docs | Function expression
- SentinelOne blog | JavaScript Stack Trace: Understanding It and Using It to Debug
Note: None person or website mentioned in this article is sponsoring this content
Until the next time!
I'll upload the next part of this series next Tuesday, October 11th. If you liked this one, stick with me!
Did I missed anything? I'm pretty sure there is a lot more to say about this, feel welcome to write your comments below!
Top comments (5)
I always confuse those 2 terms.
Do I understand correctly, an expression we assign to a variable (we get value) but a declaration we do not get value?
Interesting question, a declaration is made with the keyword
function
and they are not dependent of a variable, and they aren't anonymous, they are available in their scope. A function expression goes beyond being defined in a variable, for example, a function expression could be passed in a function argument, for example...getData(function(){/*This is a callback*/})
.Awesome. Thanks
ะกongratulations ๐ฅณ! Your article hit the top posts for the week - dev.to/fruntend/top-10-posts-for-f...
Keep it up ๐ซฐ
Hello! ๐
Thanks a lot for taking the time to feature me in your post, I'm glad you liked this article, I've been spending many hours writing the articles of this series.