Both, function expression and function statement/declaration, can be used to create a function:
// function declaration/statement
function stmt() {
// ...
}
// function expression
const expr = function () {
// ...
};
The main differences between the two are in terms of the following:
Hoisting
Function statements are hoisted to the top of the enclosing function or global scope. This means that you can call the function before it is declared:
hoisted(); // 'foo'
function hoisted() {
console.log('foo');
}
Same is not true with function expressions, as they are not hoisted. This is true, regardless of whether you use var, const or let to create a function expression. Consider, for example, the following:
// ReferenceError: notHoisted is not defined
notHoisted();
const notHoisted = function() {
console.log('foo');
};
// ReferenceError: notHoisted is not defined
notHoisted();
let notHoisted = function() {
console.log('foo');
};
// TypeError: notHoisted is not a function
notHoisted();
var notHoisted = function() {
console.log('foo');
};
Mutability
Function statements can be overridden (and are, therefore, mutable):
function foo() {
console.log('foo');
}
foo(); // 'bar'
function foo() {
console.log('bar');
}
Function expressions declared as a let or const cannot be redeclared within the local scope:
const foo = function() {
console.log('foo');
}
// SyntaxError: Identifier 'foo' has already been declared
const foo = function() {
console.log('bar');
}
let foo = function() {
console.log('foo');
}
// SyntaxError: Identifier 'foo' has already been declared
let foo = function() {
console.log('bar');
}
const foo = function() {
console.log('foo');
}
// SyntaxError: Identifier 'foo' has already been declared
var foo = function() {
console.log('bar');
}
Naming
Function name is required in a function statement/declaration; it has the following syntax:
function name([param1, ..., paramN]) {
[statements]
}
For example:
function foo() {
// ...
}
On the other hand, function name is optional in a function expression, which has the following syntax:
function [name]([param1, ..., paramN]]) {
statements
}
For example:
// unnamed function expression
const foo = function() {
// ...
};
// named function expression
const foo = function bar() {
console.log(123);
};
console.log(foo.name); // 'bar'
console.log(foo()); // 123
console.log(typeof bar); // undefined
This post was published by Daniyal Hamid. Daniyal currently works as the Head of Engineering in Germany and has 20+ years of experience in software engineering, design and marketing. Please show your love and support by sharing this post.