There are subtle differences between function declarations and expressions which are rarely understood by JavaScript beginners. This article will review their differences and suggest when to use each. First, an example of each:
Function declaration:
function helloWorld() {
console.log('Hello world!');
}
Function expression:
var helloWorld = function() {
console.log('Hello world!');
};
Function declarations
First, we'll review the simpler/more straightforward of the two options: function declarations. They resemble function definitions in other languages. Declarations start with the function
keyword, followed by the required function name (in the above, helloWorld
), and the function body.
Declarations are ideal when writing a function that will be called throughout the global scope of the program. One handy feature of function declaration is that declared functions are "hoisted", meaning that the definition is moved to the top of the program scope before the program is executed. This essentially means that the function can be called above its own declaration. For example:
helloWorldDeclared(); // => Hello world!
helloWorldExpressed(); // => TypeError: helloWorldExpressed is not a function
var helloWorldExpressed = function() {
console.log('Hello world!');
};
function helloWorldDeclared() {
console.log('Hello world!');
}
Function expressions
While neither expressions nor declarations are better, function expressions do offer more possibilities. Here are some cases where expressions come in handy:
Conditional function creation
Conditionally declared functions are not consistently implemented across browsers, so for production-quality code, expressions are better.
Immediately invoked function expressions (IIFEs)
IIFEs are primarily used because they allow for private member variables. As the name implies, IIFEs are expressions which are invoked upon definition. By defining functions within IIFEs, we can create variables which are no longer accessible in the outer function scope. For example:
var HelloWorld = (function() {
var greetee = "world";
var HelloWorldInner = function() {
this.getGreetee = function() {
return greetee;
};
this.setGreetee = function(value) {
name = greetee;
};
};
return HelloWorldInner;
})();
var hw = new HelloWorld();
hw.greetee = "Max";
hw.getGreetee(); // => world
Callback functions
While functions defined via declaration can be passed into callback functions, expressions are sometimes preferable because the passed-in function isn't used outside of the callback. So the unnamed function expression can be passed directly into the callback call.
Anonymous function creation
While function declarations require that a name be assigned to the function, expressions do not have that requirement. If a function expression is assigned to a variable, it adopts the name of the variable.
Arrow expressions
Like lambda functions in other languages, arrow expressions offer a succinct format for function definition. For example:
var adder = (a, b) => a + b;
console.log(adder(1,2)); // => 3
Using the Function
constructor
Using the Function
constructor explicitly is seldom your best option; according to MDN docs, it "suffers from security and similar (but far less significant) performance issues to eval
". While I don't recommend using the Function
constructor I wanted to call it out as a lesser known option. Example:
const helloWorld = new Function('console.log("Hello world!")');
helloWorld(); // => Hello world!
Top comments (2)
In think there is a typo mistake on your function:
var adder = (a,b) => {a + b}
I think it should return something in the function block.
Please check again!
Thank you! Accidentally included the curly brackets - should be good now.