ā¹ļø Skipped - page is already crawled
| Filter | Status | Condition | Details |
|---|---|---|---|
| HTTP status | PASS | download_http_code = 200 | HTTP 200 |
| Age cutoff | PASS | download_stamp > now() - 6 MONTH | 0 months ago |
| History drop | PASS | isNull(history_drop_reason) | No drop reason |
| Spam/ban | PASS | fh_dont_index != 1 AND ml_spam_score = 0 | ml_spam_score=0 |
| Canonical | PASS | meta_canonical IS NULL OR = '' OR = src_unparsed | Not set |
| Property | Value |
|---|---|
| URL | https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/ |
| Last Crawled | 2026-04-09 19:03:56 (6 hours ago) |
| First Indexed | 2017-09-09 23:32:16 (8 years ago) |
| HTTP Status Code | 200 |
| Meta Title | JavaScript Function Declaration: The 6 Ways |
| Meta Description | Six ways to declare (define) JavaScript functions: function declaration, function expression, arrow function, and more. Pick the one you need. |
| Meta Canonical | null |
| Boilerpipe Text | A
function
is a parametric block of code defined once and called multiple times later.
In JavaScript a function is composed of many parts:
JavaScript code that forms the function body
The list of parameters
The variables accessible from the lexical scope
The returned value
The context
this
when the function is invoked
Named or an anonymous function
The variable that holds the function object
arguments
object (or missing in an arrow function)
This post shows you six approaches to declare (aka define) JavaScript functions: the syntax, examples, and common pitfalls. Moreover, you will understand when to use a specific function type in certain circumstances.
Table of Contents
1. Function declaration
1.1 A regular function
1.2 Difference from function expression
1.3 Function declaration in conditionals
2. Function expression
2.1 Named function expression
2.2 Favor named function expression
3. Shorthand method definition
3.1 Computed property names and methods
4. Arrow function
4.1 Context transparency
4.2 Short callbacks
5. Generator function
6. One more thing: new Function
7. In the end, which way is better?
1. Function declaration
A function declaration
(also known as
function definition
) is made of
function
keyword, followed by an obligatory function name, a list of parameters in a pair of parenthesis
(para1, ..., paramN)
and a pair of curly braces
{...}
that delimits the body code.
An example of a function declaration:
// function declaration
function isEven(num) {
return num % 2 === 0;
}
console.log(isEven(24)); // => true
console.log(isEven(11)); // => false
Open the demo.
function isEven(num) {...}
is a function declaration that defines
isEven
function, which determines if a number is even.
The function declaration
creates a variable
in the current scope with the identifier equal to the function name. This variable holds the function object.
The function variable is
hoisted
up to the top of the current scope, which means that the function can be invoked before the declaration (see
this chapter
for more details).
The created function is
named
, which means that the
name
property of the function object holds its name. It is useful when viewing the call stack: in debugging or error message reading.
Let's see these properties in an example:
// Hoisted variable
console.log(hello('Aliens')); // => 'Hello Aliens!'
// Named function
console.log(hello.name) // => 'hello'
// Variable holds the function object
console.log(typeof hello); // => 'function'
function hello(name) {
return `Hello ${name}!`;
}
Open the demo.
The function declaration
function hello(name) {...}
create a variable
hello
that is hoisted to the top of the current scope.
hello
variable holds the function object and
hello.name
contains the function name:
'hello'
.
1.1 A regular function
The function declaration is useful when a regular function is needed. Regular means that you declare the function once and later invoke it in many different places. This is the basic scenario:
function sum(a, b) {
return a + b;
}
console.log(sum(5, 6)); // => 11
console.log([3, 7].reduce(sum)) // => 10
Open the demo.
Because the function declaration creates a variable in the current scope, it is also useful for recursion or detaching event listeners. Contrary to function expressions or arrow functions, that do not create a binding with the function variable by its name.
For example, to calculate recursively the factorial you have to access the function inside:
function factorial(n) {
if (n === 0) {
return 1;
}
return n * factorial(n - 1);
}
console.log(factorial(4)); // => 24
Open the demo.
Inside
factorial()
a recursive call is made using the variable that holds the function:
factorial(n - 1)
.
It is possible to use a function expression and assign it to a regular variable, e.g.
const factorial = function(n) {...}
. But the function declaration
function factorial(n)
is more compact (no need for
const
and
=
).
An important property of the function declaration is its hoisting mechanism. It allows using the function before the declaration in the same scope.
Hoisting is useful in some situations. For example, when you'd like to call the function at the beginning of a script. The function implementation can be located below in the file, so you may not even scroll there.
You can read more details about function declaration hoisting
here
.
1.2 Difference from function expression
It is easy to
confuse the function declaration and the function expression
. They look very similar but produce functions with different properties.
An easy-to-remember rule: the
function declaration
in a statement always
starts
with the keyword
function
. Otherwise it's a
function expression
(see
2.
).
The following sample is a function declaration where the statement
starts
with
function
keyword:
// Function declaration: starts with "function"
function isNil(value) {
return value == null;
}
In the case of function expressions the JavaScript statement
does not start
with
function
keyword (it is somewhere in the middle of the statement code):
// Function expression: starts with "const"
const isTruthy = function(value) {
return !!value;
};
// Function expression: an argument for .filter()
const numbers = ([1, false, 5]).filter(function(item) {
return typeof item === 'number';
});
// Function expression (IIFE): starts with "("
(function messageFunction(message) {
return message + ' World!';
})('Hello');
1.3 Function declaration in conditionals
Some JavaScript environments throw a reference error when invoking a function whose declaration appears within blocks
{...}
of
if
,
for
, or
while
statements.
Let's enable the strict mode and see what happens when a function is declared in a conditional:
(function() {
'use strict';
if (true) {
function ok() {
return 'true ok';
}
} else {
function ok() {
return 'false ok';
}
}
console.log(typeof ok === 'undefined'); // => true
console.log(ok()); // Throws "ReferenceError: ok is not defined"
})();
Open the demo.
When calling
ok()
, JavaScript throws
ReferenceError: ok is not defined
, because the function declaration is inside a conditional block.
The function declaration in conditionals is allowed in non-strict mode, which makes it even more confusing.
As a general rule for these situations, when a function should be created by conditions - use a function expression. Let's see how it is possible:
(function() {
'use strict';
let ok;
if (true) {
ok = function() {
return 'true ok';
};
} else {
ok = function() {
return 'false ok';
};
}
console.log(typeof ok === 'function'); // => true
console.log(ok()); // => 'true ok'
})();
Open the demo.
ok
variable is assigned to one or another function depending on the condition. Invoking
ok()
works fine, without errors.
2. Function expression
A function expression
is determined by a
function
keyword, followed by an optional function name, a list of parameters in a pair of parenthesis
(para1, ..., paramN)
and a pair of curly braces
{ ... }
that delimits the body code.
Some samples of the function expression:
const count = function(array) { // Function expression
return array.length;
}
console.log(count([5, 7, 8])); // => 3
const methods = {
numbers: [1, 5, 8],
sum: function() { // Function expression
return this.numbers.reduce(function(acc, num) { // func. expression
return acc + num;
});
}
}
console.log(methods.sum()); // => 14
Open the demo.
The function expression creates a function object that can be used in different situations:
Assigned to a variable as an object
count = function(...) {...}
Create a method on an object
sum: function() {...}
Use the function as a callback
array.map(function(...) {...})
The function expression is the working horse in JavaScript. Usually, you deal with this type of function declaration, alongside the arrow function (if you prefer short syntax and lexical context).
2.1 Named function expression
A function is anonymous when it does not have a name (
name
property is an empty string
''
):
const name = (function(variable) {return typeof variable; }).name
console.log(name); // => ''
Open the demo.
This is an anonymous function, which name is an empty string.
Sometimes the function name can be inferred. For example, when the anonymous is assigned to a variable:
const myFunctionVar = function(variable) {
return typeof variable;
};
console.log(myFunctionVar.name); // => 'myFunctionVar'
Open the demo.
The anonymous function name is
'myFunctionVar'
, because
myFunctionVar
variable name is used to infer the function name.
When the expression has the name specified, this is a
named function expression
. It has some additional properties compared to simple function expression:
A named function is created, i.e.
name
property holds the function name
Inside the function body a variable with the same name holds the function object
Let's use the above example, but set a name in the function expression:
const myFunctionVar = function getNumber() {
console.log(typeof funName === 'function'); // => true
return 42;
}
console.log(myFunctionVar()); // => 42
console.log(myFunctionVar.name); // => 'getNumber'
console.log(typeof getNumber); // => 'undefined'
Open the demo.
function getNumber() {...}
is a named function expression. The variable
getNumber
is accessible within function scope, but not outside. Either way, the property
name
of the function object holds the name:
getNumber
.
2.2 Favor named function expression
When a function expression
const fun = function() {}
is assigned to a variable, some engines infer the function name from this variable. However, callbacks might be passed as anonymous function expressions, without storing into variables: so the engine
cannot determine its name
.
It is reasonable
to favor named functions to anonymous ones to gain benefits like:
The error messages and call stacks show more detailed information when using the function names
More comfortable debugging by reducing the number of
anonymous
stack names
The function name says what the function does
You can access the function inside its scope for recursive calls or detaching event listeners
3. Shorthand method definition
Shorthand method definition
is used in a method declaration on object literals and ES2015 classes. You can define them using a function name, followed by a list of parameters in a pair of parenthesis
(para1, ..., paramN)
and a pair of curly braces
{ ... }
that delimits the body statements.
The following example uses a shorthand method definition in an object literal:
const collection = {
items: [],
add(...items) {
this.items.push(...items);
},
get(index) {
return this.items[index];
}
};
collection.add('C', 'Java', 'PHP');
console.log(collection.get(1)); // => 'Java'
Open the demo.
add()
and
get()
methods in
collection
object are defined using short method definition. These methods are called as usual:
collection.add(...)
and
collection.get(...)
.
The short approach of method definition has several benefits over traditional property definition with a name, colon
:
and a function expression
add: function(...) {...}
:
A shorter syntax is easier to understand
Shorthand method definition creates a named function, contrary to a function expression. It is useful for debugging.
The
class
syntax requires method declarations in a short form:
class Star {
constructor(name) {
this.name = name;
}
getMessage(message) {
return this.name + message;
}
}
const sun = new Star('Sun');
console.log(sun.getMessage(' is shining')); // => 'Sun is shining'
Open the demo.
3.1 Computed property names and methods
ECMAScript 2015 adds a nice feature: computed property names in object literals and classes.
The computed properties use a slight different syntax
[methodName]() {...}
, so the method definition looks this way:
const addMethod = 'add';
const getMethod = 'get';
const collection = {
items: [],
[addMethod](...items) {
this.items.push(...items);
},
[getMethod](index) {
return this.items[index];
}
};
collection[addMethod]('C', 'Java', 'PHP');
console.log(collection[getMethod](1)); // => 'Java'
Open the demo.
[addMethod](...) {...}
and
[getMethod](...) {...}
are shorthand method declarations with computed property names.
4. Arrow function
An arrow function
is defined using a pair of parenthesis that contains the list of parameters
(param1, param2, ..., paramN)
, followed by a fat arrow
=>
and a pair of curly braces
{...}
that delimits the body statements.
When the arrow function has only one parameter, the pair of parentheses can be omitted. When it contains a single statement, the curly braces can be omitted too.
Let's see the arrow function basic usage:
const absValue = (number) => {
if (number < 0) {
return -number;
}
return number;
}
console.log(absValue(-10)); // => 10
console.log(absValue(5)); // => 5
Open the demo.
absValue
is an arrow function that calculates the absolute value of a number.
The function declared using a fat arrow has the following properties:
The arrow function does not create its execution context but takes it lexically (contrary to function expression or function declaration, which creates its own
this
depending on invocation)
The arrow function is anonymous. However, the engine can infer its name from the variable holding the function
arguments
object is not available in the arrow function (contrary to other declaration types that provide
arguments
object). You are free to use rest parameters
(...params)
, though.
4.1 Context transparency
this
keyword is a confusing aspect of JavaScript (check
this article
for a detailed explanation of
this
).
Because functions create their execution context, often it is difficult to detect
this
value.
ECMAScript 2015 improves
this
usage by introducing the arrow function, which takes the context lexically (or simply uses
this
from the immediate outer scope). This is nice because you don't have to use
myFunc.bind(this)
or store the context
const self = this
when a function needs the enclosing context.
Let's see how
this
is accessed from the outer function:
class Numbers {
constructor(array) {
this.array = array;
}
addNumber(number) {
if (number !== undefined) {
this.array.push(number);
}
return (number) => {
console.log(this === numbersObject); // => true
this.array.push(number);
};
}
}
const numbersObject = new Numbers([]);
const addMethod = numbersObject.addNumber();
addMethod(1);
addMethod(5);
console.log(numbersObject.array); // => [1, 5]
Open the demo.
Numbers
class holds an array of numbers and provides a method
addNumber()
to insert new numbers.
When
addNumber()
is called without arguments, a closure is returned that allows inserting numbers. This closure is an arrow function that has
this
as
numbersObject
instance because the context is taken lexically from
addNumbers()
method.
Without the arrow function, you have to manually fix the context. It means using workarounds like
array.bind(thisVal)
method:
//...
return function(number) {
console.log(this === numbersObject); // => true
this.array.push(number);
}.bind(this);
//...
or store the context into a separate variable
var self = this
:
//...
const self = this;
return function(number) {
console.log(self === numbersObject); // => true
self.array.push(number);
};
//...
Context transparency can be used when you want to keep
this
as is, taken from the enclosing context.
4.2 Short callbacks
When creating an arrow function, the parenthesis pairs and curly braces are optional for a single parameter and single body statement. This helps in creating very short callback functions.
Let's make a function that finds if an array contains
0
:
const numbers = [1, 5, 10, 0];
console.log(numbers.some(item => item === 0)); // => true
Open the demo.
item => item === 0
is an arrow function that looks straightforward.
Note that nested short arrow functions are difficult to read. The convenient way to use the shortest arrow function form is a single callback (without nesting).
If necessary, use the expanded syntax of arrow functions when writing nested arrow functions. It's just easier to read.
5. Generator function
The generator function in JavaScript returns a
Generator object
. Its syntax is similar to function expression, function declaration, or method declaration, just that it requires a star character
*
.
The generator function can be declared in the following forms:
a. Function declaration form
function* <name>()
:
function* indexGenerator(){
var index = 0;
while(true) {
yield index++;
}
}
const g = indexGenerator();
console.log(g.next().value); // => 0
console.log(g.next().value); // => 1
Open the demo.
b. Function expression form
function* ()
:
const indexGenerator = function* () {
let index = 0;
while(true) {
yield index++;
}
};
const g = indexGenerator();
console.log(g.next().value); // => 0
console.log(g.next().value); // => 1
Open the demo.
c. Shorthand method definition form
*<name>()
:
const obj = {
*indexGenerator() {
var index = 0;
while(true) {
yield index++;
}
}
}
const g = obj.indexGenerator();
console.log(g.next().value); // => 0
console.log(g.next().value); // => 1
Open the demo.
In all 3 cases, the generator function returns the generator object
g
. Later
g
is used to generate a series of incremented numbers.
6. One more thing: new Function
In JavaScript functions are first-class objects: a function is a regular object of type
function
.
The ways of the declaration described above create the same function object type. Let's see an example:
function sum1(a, b) {
return a + b;
}
const sum2 = function(a, b) {
return a + b;
}
const sum3 = (a, b) => a + b;
console.log(typeof sum1 === 'function'); // => true
console.log(typeof sum2 === 'function'); // => true
console.log(typeof sum3 === 'function'); // => true
Open the demo.
The function object type has a constructor:
Function
.
When
Function
is invoked as a constructor
new Function(arg1, arg2, ..., argN, bodyString)
, a new function is created. The arguments
arg1, args2, ..., argN
passed to the constructor become the parameter names for the new function, and the last argument
bodyString
is used as the function body code.
Let's create a function that sums two numbers:
const sumFunction = new Function('numberA', 'numberB',
'return numberA + numberB'
);
console.log(sumFunction(10, 15)); // => 25
Open the demo.
sumFunction
created with
Function
constructor invocation has parameters
numberA
and
numberB
and the body
return numberA + numberB
.
The functions created this way don't have access to the current scope, thus closures cannot be created. They are always created in the global scope.
One
possible
application of
new Function
is a
better way
to access the global object in a browser or NodeJS script:
(function() {
'use strict';
const global = new Function('return this')();
console.log(global === window); // => true
console.log(this === window); // => false
})();
Open the demo.
Remember that functions
seldom
should be declared using
new Function()
. Because the function body is evaluated on runtime, this approach inherits many
eval()
usage
problems
: security risks, harder debugging, no way to apply engine optimizations, no editor auto-complete.
7. In the end, which way is better?
There is no winner or loser. The decision of which declaration type to choose depends on the situation.
There are some rules however that you may follow in common situations.
If the function uses
this
from the enclosing function, the arrow function is a good solution. When the callback function has one short statement, the arrow function is a good option too, because it creates short and light code.
For a shorter syntax when declaring methods on object literals, the shorthand method declaration is preferable.
new Function
way to declare functions normally should not be used. Mainly because it opens potential security risks, doesn't allow code auto-complete in editors, and loses the engine optimizations.
Do you prefer arrow functions or function expressions?! |
| Markdown | [![Home]() ](https://dmitripavlutin.com/)
[Dmitri Pavlutin](https://dmitripavlutin.com/)
I help developers understand Frontend technologies
[RSS](https://dmitripavlutin.com/rss.xml)[Search](https://dmitripavlutin.com/search/)[All posts](https://dmitripavlutin.com/all-posts/)[About](https://dmitripavlutin.com/about-me/)

![Post cover]()

# JavaScript Function Declaration: The 6 Ways
Updated March 19, 2023
[javascript](https://dmitripavlutin.com/tag/javascript/)[function](https://dmitripavlutin.com/tag/function/)[arrow-function](https://dmitripavlutin.com/tag/arrow-function/)
[\-- Comments](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#comments "Jump to comments section")
A **function** is a parametric block of code defined once and called multiple times later.
In JavaScript a function is composed of many parts:
- JavaScript code that forms the function body
- The list of parameters
- The variables accessible from the lexical scope
- The returned value
- The context `this` when the function is invoked
- Named or an anonymous function
- The variable that holds the function object
- `arguments` object (or missing in an arrow function)
This post shows you six approaches to declare (aka define) JavaScript functions: the syntax, examples, and common pitfalls. Moreover, you will understand when to use a specific function type in certain circumstances.
### Table of Contents
- [1\. Function declaration](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#1-function-declaration)
- [1\.1 A regular function](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#11-a-regular-function)
- [1\.2 Difference from function expression](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#12-difference-from-function-expression)
- [1\.3 Function declaration in conditionals](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#13-function-declaration-in-conditionals)
- [2\. Function expression](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#2-function-expression)
- [2\.1 Named function expression](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#21-named-function-expression)
- [2\.2 Favor named function expression](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#22-favor-named-function-expression)
- [3\. Shorthand method definition](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#3-shorthand-method-definition)
- [3\.1 Computed property names and methods](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#31-computed-property-names-and-methods)
- [4\. Arrow function](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#4-arrow-function)
- [4\.1 Context transparency](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#41-context-transparency)
- [4\.2 Short callbacks](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#42-short-callbacks)
- [5\. Generator function](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#5-generator-function)
- [6\. One more thing: new Function](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#6-one-more-thing-new-function)
- [7\. In the end, which way is better?](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#7-in-the-end-which-way-is-better)
## 1\. Function declaration
> **A function declaration** (also known as **function definition**) is made of `function` keyword, followed by an obligatory function name, a list of parameters in a pair of parenthesis `(para1, ..., paramN)` and a pair of curly braces `{...}` that delimits the body code.
An example of a function declaration:
```
// function declarationfunction isEven(num) {return num % 2 === 0;}console.log(isEven(24)); // => trueconsole.log(isEven(11)); // => false
```
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/r0qnok2j/1/)
`function isEven(num) {...}` is a function declaration that defines `isEven` function, which determines if a number is even.
The function declaration **creates a variable** in the current scope with the identifier equal to the function name. This variable holds the function object.
The function variable is **hoisted** up to the top of the current scope, which means that the function can be invoked before the declaration (see [this chapter](https://dmitripavlutin.com/javascript-hoisting-in-details/#5-function-declarations) for more details).
The created function is **named**, which means that the `name` property of the function object holds its name. It is useful when viewing the call stack: in debugging or error message reading.
Let's see these properties in an example:
```
// Hoisted variableconsole.log(hello('Aliens')); // => 'Hello Aliens!'// Named functionconsole.log(hello.name) // => 'hello'// Variable holds the function objectconsole.log(typeof hello); // => 'function'function hello(name) {return `Hello ${name}!`;}
```
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/Lvbp2n4e/)
The function declaration `function hello(name) {...}` create a variable `hello` that is hoisted to the top of the current scope. `hello` variable holds the function object and `hello.name` contains the function name: `'hello'`.
### 1\.1 A regular function
The function declaration is useful when a regular function is needed. Regular means that you declare the function once and later invoke it in many different places. This is the basic scenario:
```
function sum(a, b) {return a + b;}console.log(sum(5, 6)); // => 11console.log([3, 7].reduce(sum)) // => 10
```
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/y2xa3pzg/2/)
Because the function declaration creates a variable in the current scope, it is also useful for recursion or detaching event listeners. Contrary to function expressions or arrow functions, that do not create a binding with the function variable by its name.
For example, to calculate recursively the factorial you have to access the function inside:
```
function factorial(n) {if (n === 0) {return 1;}return n * factorial(n - 1);}console.log(factorial(4)); // => 24
```
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/dL9psu6t/)
Inside `factorial()` a recursive call is made using the variable that holds the function: `factorial(n - 1)`.
It is possible to use a function expression and assign it to a regular variable, e.g. `const factorial = function(n) {...}`. But the function declaration `function factorial(n)` is more compact (no need for `const` and `=`).
An important property of the function declaration is its hoisting mechanism. It allows using the function before the declaration in the same scope.
Hoisting is useful in some situations. For example, when you'd like to call the function at the beginning of a script. The function implementation can be located below in the file, so you may not even scroll there.
You can read more details about function declaration hoisting [here](https://dmitripavlutin.com/javascript-hoisting-in-details/#5-function-declarations).
### 1\.2 Difference from function expression
It is easy to [confuse the function declaration and the function expression](https://dmitripavlutin.com/javascript-function-expressions-and-declarations/). They look very similar but produce functions with different properties.
An easy-to-remember rule: the *function declaration* in a statement always **starts** with the keyword `function`. Otherwise it's a *function expression* (see [2\.](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#2functionexpression)).
The following sample is a function declaration where the statement **starts** with `function` keyword:
```
// Function declaration: starts with "function"function isNil(value) {return value == null;}
```
In the case of function expressions the JavaScript statement **does not start** with `function` keyword (it is somewhere in the middle of the statement code):
```
// Function expression: starts with "const"const isTruthy = function(value) {return !!value;};// Function expression: an argument for .filter()const numbers = ([1, false, 5]).filter(function(item) {return typeof item === 'number';});// Function expression (IIFE): starts with "("(function messageFunction(message) {return message + ' World!';})('Hello');
```
### 1\.3 Function declaration in conditionals
Some JavaScript environments throw a reference error when invoking a function whose declaration appears within blocks `{...}` of `if`, `for`, or `while` statements.
Let's enable the strict mode and see what happens when a function is declared in a conditional:
```
(function() {'use strict';if (true) {function ok() {return 'true ok';}} else {function ok() {return 'false ok';}}console.log(typeof ok === 'undefined'); // => trueconsole.log(ok()); // Throws "ReferenceError: ok is not defined"})();
```
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/jfaw7t8k/)
When calling `ok()`, JavaScript throws `ReferenceError: ok is not defined`, because the function declaration is inside a conditional block.
The function declaration in conditionals is allowed in non-strict mode, which makes it even more confusing.
As a general rule for these situations, when a function should be created by conditions - use a function expression. Let's see how it is possible:
```
(function() {'use strict';let ok;if (true) {ok = function() {return 'true ok';};} else {ok = function() {return 'false ok';};}console.log(typeof ok === 'function'); // => trueconsole.log(ok()); // => 'true ok'})();
```
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/gp8fco6q/)
`ok` variable is assigned to one or another function depending on the condition. Invoking `ok()` works fine, without errors.
## 2\. Function expression
> **A function expression** is determined by a `function` keyword, followed by an optional function name, a list of parameters in a pair of parenthesis `(para1, ..., paramN)` and a pair of curly braces `{ ... }` that delimits the body code.
Some samples of the function expression:
```
const count = function(array) { // Function expressionreturn array.length;}console.log(count([5, 7, 8])); // => 3const methods = {numbers: [1, 5, 8],sum: function() { // Function expressionreturn this.numbers.reduce(function(acc, num) { // func. expressionreturn acc + num;});}}console.log(methods.sum()); // => 14
```
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/kz204ynm/)
The function expression creates a function object that can be used in different situations:
- Assigned to a variable as an object `count = function(...) {...}`
- Create a method on an object `sum: function() {...}`
- Use the function as a callback `array.map(function(...) {...})`
The function expression is the working horse in JavaScript. Usually, you deal with this type of function declaration, alongside the arrow function (if you prefer short syntax and lexical context).
### 2\.1 Named function expression
A function is anonymous when it does not have a name (`name` property is an empty string `''`):
```
const name = (function(variable) {return typeof variable; }).nameconsole.log(name); // => ''
```
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/4tw57ubm/)
This is an anonymous function, which name is an empty string.
Sometimes the function name can be inferred. For example, when the anonymous is assigned to a variable:
```
const myFunctionVar = function(variable) {return typeof variable;};console.log(myFunctionVar.name); // => 'myFunctionVar'
```
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/m45pdbwh/)
The anonymous function name is `'myFunctionVar'`, because `myFunctionVar` variable name is used to infer the function name.
When the expression has the name specified, this is a **named function expression**. It has some additional properties compared to simple function expression:
- A named function is created, i.e. `name` property holds the function name
- Inside the function body a variable with the same name holds the function object
Let's use the above example, but set a name in the function expression:
```
const myFunctionVar = function getNumber() {console.log(typeof funName === 'function'); // => truereturn 42;}console.log(myFunctionVar()); // => 42console.log(myFunctionVar.name); // => 'getNumber'console.log(typeof getNumber); // => 'undefined'
```
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/4kgmLt8b/)
`function getNumber() {...}` is a named function expression. The variable `getNumber` is accessible within function scope, but not outside. Either way, the property `name` of the function object holds the name: `getNumber`.
### 2\.2 Favor named function expression
When a function expression `const fun = function() {}` is assigned to a variable, some engines infer the function name from this variable. However, callbacks might be passed as anonymous function expressions, without storing into variables: so the engine *cannot determine its name*.
[It is reasonable](https://ultimatecourses.com/blog/avoiding-anonymous-javascript-functions) to favor named functions to anonymous ones to gain benefits like:
- The error messages and call stacks show more detailed information when using the function names
- More comfortable debugging by reducing the number of *anonymous* stack names
- The function name says what the function does
- You can access the function inside its scope for recursive calls or detaching event listeners
## 3\. Shorthand method definition
> **Shorthand method definition** is used in a method declaration on object literals and ES2015 classes. You can define them using a function name, followed by a list of parameters in a pair of parenthesis `(para1, ..., paramN)` and a pair of curly braces `{ ... }` that delimits the body statements.
The following example uses a shorthand method definition in an object literal:
```
const collection = {items: [],add(...items) {this.items.push(...items);},get(index) {return this.items[index];}};collection.add('C', 'Java', 'PHP');console.log(collection.get(1)); // => 'Java'
```
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/brhkdzca/)
`add()` and `get()` methods in `collection` object are defined using short method definition. These methods are called as usual: `collection.add(...)` and `collection.get(...)`.
The short approach of method definition has several benefits over traditional property definition with a name, colon `:` and a function expression `add: function(...) {...}`:
- A shorter syntax is easier to understand
- Shorthand method definition creates a named function, contrary to a function expression. It is useful for debugging.
The `class` syntax requires method declarations in a short form:
```
class Star {constructor(name) {this.name = name;}getMessage(message) {return this.name + message;}}const sun = new Star('Sun');console.log(sun.getMessage(' is shining')); // => 'Sun is shining'
```
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/dq06y5ej/)
### 3\.1 Computed property names and methods
ECMAScript 2015 adds a nice feature: computed property names in object literals and classes.
The computed properties use a slight different syntax `[methodName]() {...}`, so the method definition looks this way:
```
const addMethod = 'add';const getMethod = 'get';const collection = {items: [],[addMethod](...items) {this.items.push(...items);},[getMethod](index) {return this.items[index];}};collection[addMethod]('C', 'Java', 'PHP');console.log(collection[getMethod](1)); // => 'Java'
```
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/5La81c07/)
`[addMethod](...) {...}` and `[getMethod](...) {...}` are shorthand method declarations with computed property names.
## 4\. Arrow function
> **An arrow function** is defined using a pair of parenthesis that contains the list of parameters `(param1, param2, ..., paramN)`, followed by a fat arrow `=>` and a pair of curly braces `{...}` that delimits the body statements.
When the arrow function has only one parameter, the pair of parentheses can be omitted. When it contains a single statement, the curly braces can be omitted too.
Let's see the arrow function basic usage:
```
const absValue = (number) => {if (number < 0) {return -number;}return number;}console.log(absValue(-10)); // => 10console.log(absValue(5)); // => 5
```
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/16jz35w8/)
`absValue` is an arrow function that calculates the absolute value of a number.
The function declared using a fat arrow has the following properties:
- The arrow function does not create its execution context but takes it lexically (contrary to function expression or function declaration, which creates its own `this` depending on invocation)
- The arrow function is anonymous. However, the engine can infer its name from the variable holding the function
- `arguments` object is not available in the arrow function (contrary to other declaration types that provide `arguments` object). You are free to use rest parameters `(...params)`, though.
### 4\.1 Context transparency
`this` keyword is a confusing aspect of JavaScript (check [this article](https://dmitripavlutin.com/gentle-explanation-of-this-in-javascript/) for a detailed explanation of `this`).
Because functions create their execution context, often it is difficult to detect `this` value.
ECMAScript 2015 improves `this` usage by introducing the arrow function, which takes the context lexically (or simply uses `this` from the immediate outer scope). This is nice because you don't have to use `myFunc.bind(this)` or store the context `const self = this` when a function needs the enclosing context.
Let's see how `this` is accessed from the outer function:
```
class Numbers {constructor(array) {this.array = array;}addNumber(number) {if (number !== undefined) {this.array.push(number);}return (number) => {console.log(this === numbersObject); // => truethis.array.push(number);};}}const numbersObject = new Numbers([]);const addMethod = numbersObject.addNumber();addMethod(1);addMethod(5);console.log(numbersObject.array); // => [1, 5]
```
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/40d1kq9n/)
`Numbers` class holds an array of numbers and provides a method `addNumber()` to insert new numbers.
When `addNumber()` is called without arguments, a closure is returned that allows inserting numbers. This closure is an arrow function that has `this` as `numbersObject` instance because the context is taken lexically from `addNumbers()` method.
Without the arrow function, you have to manually fix the context. It means using workarounds like `array.bind(thisVal)` method:
```
//...return function(number) {console.log(this === numbersObject); // => truethis.array.push(number);}.bind(this);//...
```
or store the context into a separate variable `var self = this`:
```
//...const self = this;return function(number) {console.log(self === numbersObject); // => trueself.array.push(number);};//...
```
Context transparency can be used when you want to keep `this` as is, taken from the enclosing context.
### 4\.2 Short callbacks
When creating an arrow function, the parenthesis pairs and curly braces are optional for a single parameter and single body statement. This helps in creating very short callback functions.
Let's make a function that finds if an array contains `0`:
```
const numbers = [1, 5, 10, 0];console.log(numbers.some(item => item === 0)); // => true
```
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/9pj1ukwf/)
`item => item === 0` is an arrow function that looks straightforward.
Note that nested short arrow functions are difficult to read. The convenient way to use the shortest arrow function form is a single callback (without nesting).
If necessary, use the expanded syntax of arrow functions when writing nested arrow functions. It's just easier to read.
## 5\. Generator function
The generator function in JavaScript returns a [Generator object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator). Its syntax is similar to function expression, function declaration, or method declaration, just that it requires a star character `*`.
The generator function can be declared in the following forms:
a. Function declaration form `function* <name>()`:
```
function* indexGenerator(){var index = 0;while(true) {yield index++;}}const g = indexGenerator();console.log(g.next().value); // => 0console.log(g.next().value); // => 1
```
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/j24k8hge/)
b. Function expression form `function* ()`:
```
const indexGenerator = function* () {let index = 0;while(true) {yield index++;}};const g = indexGenerator();console.log(g.next().value); // => 0console.log(g.next().value); // => 1
```
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/29hk1vo8/)
c. Shorthand method definition form `*<name>()`:
```
const obj = {*indexGenerator() {var index = 0;while(true) {yield index++;}}}const g = obj.indexGenerator();console.log(g.next().value); // => 0console.log(g.next().value); // => 1
```
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/dmwr2a0u/)
In all 3 cases, the generator function returns the generator object `g`. Later `g` is used to generate a series of incremented numbers.
## 6\. One more thing: new Function
In JavaScript functions are first-class objects: a function is a regular object of type `function`.
The ways of the declaration described above create the same function object type. Let's see an example:
```
function sum1(a, b) {return a + b;}const sum2 = function(a, b) {return a + b;}const sum3 = (a, b) => a + b;console.log(typeof sum1 === 'function'); // => trueconsole.log(typeof sum2 === 'function'); // => trueconsole.log(typeof sum3 === 'function'); // => true
```
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/hqw5Lz6t/)
The function object type has a constructor: [`Function`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function).
When `Function` is invoked as a constructor `new Function(arg1, arg2, ..., argN, bodyString)`, a new function is created. The arguments `arg1, args2, ..., argN` passed to the constructor become the parameter names for the new function, and the last argument `bodyString` is used as the function body code.
Let's create a function that sums two numbers:
```
const sumFunction = new Function('numberA', 'numberB','return numberA + numberB');console.log(sumFunction(10, 15)); // => 25
```
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/31zbad0q/)
`sumFunction` created with `Function` constructor invocation has parameters `numberA` and `numberB` and the body `return numberA + numberB`.
The functions created this way don't have access to the current scope, thus closures cannot be created. They are always created in the global scope.
One *possible* application of `new Function` is a [better way](https://twitter.com/WebReflection/status/269578376833024000) to access the global object in a browser or NodeJS script:
```
(function() {'use strict';const global = new Function('return this')();console.log(global === window); // => trueconsole.log(this === window); // => false})();
```
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/dyvgnL82/)
Remember that functions **seldom** should be declared using `new Function()`. Because the function body is evaluated on runtime, this approach inherits many `eval()` usage [problems](http://stackoverflow.com/a/86580/1894471): security risks, harder debugging, no way to apply engine optimizations, no editor auto-complete.
## 7\. In the end, which way is better?
There is no winner or loser. The decision of which declaration type to choose depends on the situation.
There are some rules however that you may follow in common situations.
If the function uses `this` from the enclosing function, the arrow function is a good solution. When the callback function has one short statement, the arrow function is a good option too, because it creates short and light code.
For a shorter syntax when declaring methods on object literals, the shorthand method declaration is preferable.
`new Function` way to declare functions normally should not be used. Mainly because it opens potential security risks, doesn't allow code auto-complete in editors, and loses the engine optimizations.
*Do you prefer arrow functions or function expressions?\!*
#### Like the post? Please share\!
[Suggest Improvement](https://github.com/panzerdp/dmitripavlutin.com/edit/master/posts/011-declare-function/index.md)

![Dmitri Pavlutin]()

#### About Dmitri Pavlutin
Software developer and sometimes writer. My daily routine consists of (but not limited to) drinking coffee, coding, writing, overcoming boredom š, developing [a gift boxes Shopify app](https://apps.shopify.com/boxi?utm_source=dmitripavlutin&utm_medium=referral), and [blogging about Shopify](https://boxiapps.com/blog?utm_source=dmitripavlutin&utm_medium=referral). Living in the sunny Barcelona. šŖšø
[](mailto:dmitripavlutin@gmail.com "Send an email to Dmitri Pavlutin")[](https://twitter.com/panzerdp "Dmitri Pavlutin's Twitter profile")[](https://www.facebook.com/dmitripavlutin.dev "Dmitri Pavlutin's Facebook page")[](https://www.linkedin.com/in/dmitri-pavlutin/ "Dmitri Pavlutin's Linkedin profile")

![Dmitri Pavlutin]()

### About Dmitri Pavlutin
Software developer and sometimes writer. My daily routine consists of (but not limited to) drinking coffee, coding, writing, overcoming boredom š, developing [a gift boxes Shopify app](https://apps.shopify.com/boxi?utm_source=dmitripavlutin&utm_medium=referral), and [blogging about Shopify](https://boxiapps.com/blog?utm_source=dmitripavlutin&utm_medium=referral). Living in the sunny Barcelona. šŖšø
[](mailto:dmitripavlutin@gmail.com "Send an email to Dmitri Pavlutin")[](https://twitter.com/panzerdp "Dmitri Pavlutin's Twitter profile")[](https://www.facebook.com/dmitripavlutin.dev "Dmitri Pavlutin's Facebook page")[](https://www.linkedin.com/in/dmitri-pavlutin/ "Dmitri Pavlutin's Linkedin profile")
### Popular posts
JavaScript
React
ā [JavaScript Closure: The Beginner's Friendly Guide](https://dmitripavlutin.com/javascript-closure/)
ā [Gentle Explanation of "this" in JavaScript](https://dmitripavlutin.com/gentle-explanation-of-this-in-javascript/)
ā [5 Differences Between Arrow and Regular Functions](https://dmitripavlutin.com/differences-between-arrow-and-regular-functions/)
ā [A Simple Explanation of React.useEffect()](https://dmitripavlutin.com/react-useeffect-explanation/)
ā [Your Guide to React.useCallback()](https://dmitripavlutin.com/react-usecallback/)
ā [Use React.memo() wisely](https://dmitripavlutin.com/use-react-memo-wisely/)
Ā© 2025 Dmitri Pavlutin
Licensed under [CC BY 4.0](http://creativecommons.org/licenses/by/4.0/)
[Terms](https://dmitripavlutin.com/terms/)[Privacy](https://dmitripavlutin.com/privacy-policy/)[Contact](https://dmitripavlutin.com/contact/)[About](https://dmitripavlutin.com/about-me/) |
| Readable Markdown | A **function** is a parametric block of code defined once and called multiple times later.
In JavaScript a function is composed of many parts:
- JavaScript code that forms the function body
- The list of parameters
- The variables accessible from the lexical scope
- The returned value
- The context `this` when the function is invoked
- Named or an anonymous function
- The variable that holds the function object
- `arguments` object (or missing in an arrow function)
This post shows you six approaches to declare (aka define) JavaScript functions: the syntax, examples, and common pitfalls. Moreover, you will understand when to use a specific function type in certain circumstances.
### Table of Contents
- [1\. Function declaration](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#1-function-declaration)
- [1\.1 A regular function](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#11-a-regular-function)
- [1\.2 Difference from function expression](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#12-difference-from-function-expression)
- [1\.3 Function declaration in conditionals](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#13-function-declaration-in-conditionals)
- [2\. Function expression](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#2-function-expression)
- [2\.1 Named function expression](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#21-named-function-expression)
- [2\.2 Favor named function expression](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#22-favor-named-function-expression)
- [3\. Shorthand method definition](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#3-shorthand-method-definition)
- [3\.1 Computed property names and methods](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#31-computed-property-names-and-methods)
- [4\. Arrow function](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#4-arrow-function)
- [4\.1 Context transparency](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#41-context-transparency)
- [4\.2 Short callbacks](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#42-short-callbacks)
- [5\. Generator function](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#5-generator-function)
- [6\. One more thing: new Function](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#6-one-more-thing-new-function)
- [7\. In the end, which way is better?](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#7-in-the-end-which-way-is-better)
## 1\. Function declaration
> **A function declaration** (also known as **function definition**) is made of `function` keyword, followed by an obligatory function name, a list of parameters in a pair of parenthesis `(para1, ..., paramN)` and a pair of curly braces `{...}` that delimits the body code.
An example of a function declaration:
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/r0qnok2j/1/)
`function isEven(num) {...}` is a function declaration that defines `isEven` function, which determines if a number is even.
The function declaration **creates a variable** in the current scope with the identifier equal to the function name. This variable holds the function object.
The function variable is **hoisted** up to the top of the current scope, which means that the function can be invoked before the declaration (see [this chapter](https://dmitripavlutin.com/javascript-hoisting-in-details/#5-function-declarations) for more details).
The created function is **named**, which means that the `name` property of the function object holds its name. It is useful when viewing the call stack: in debugging or error message reading.
Let's see these properties in an example:
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/Lvbp2n4e/)
The function declaration `function hello(name) {...}` create a variable `hello` that is hoisted to the top of the current scope. `hello` variable holds the function object and `hello.name` contains the function name: `'hello'`.
### 1\.1 A regular function
The function declaration is useful when a regular function is needed. Regular means that you declare the function once and later invoke it in many different places. This is the basic scenario:
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/y2xa3pzg/2/)
Because the function declaration creates a variable in the current scope, it is also useful for recursion or detaching event listeners. Contrary to function expressions or arrow functions, that do not create a binding with the function variable by its name.
For example, to calculate recursively the factorial you have to access the function inside:
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/dL9psu6t/)
Inside `factorial()` a recursive call is made using the variable that holds the function: `factorial(n - 1)`.
It is possible to use a function expression and assign it to a regular variable, e.g. `const factorial = function(n) {...}`. But the function declaration `function factorial(n)` is more compact (no need for `const` and `=`).
An important property of the function declaration is its hoisting mechanism. It allows using the function before the declaration in the same scope.
Hoisting is useful in some situations. For example, when you'd like to call the function at the beginning of a script. The function implementation can be located below in the file, so you may not even scroll there.
You can read more details about function declaration hoisting [here](https://dmitripavlutin.com/javascript-hoisting-in-details/#5-function-declarations).
### 1\.2 Difference from function expression
It is easy to [confuse the function declaration and the function expression](https://dmitripavlutin.com/javascript-function-expressions-and-declarations/). They look very similar but produce functions with different properties.
An easy-to-remember rule: the *function declaration* in a statement always **starts** with the keyword `function`. Otherwise it's a *function expression* (see [2\.](https://dmitripavlutin.com/6-ways-to-declare-javascript-functions/#2functionexpression)).
The following sample is a function declaration where the statement **starts** with `function` keyword:
In the case of function expressions the JavaScript statement **does not start** with `function` keyword (it is somewhere in the middle of the statement code):
### 1\.3 Function declaration in conditionals
Some JavaScript environments throw a reference error when invoking a function whose declaration appears within blocks `{...}` of `if`, `for`, or `while` statements.
Let's enable the strict mode and see what happens when a function is declared in a conditional:
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/jfaw7t8k/)
When calling `ok()`, JavaScript throws `ReferenceError: ok is not defined`, because the function declaration is inside a conditional block.
The function declaration in conditionals is allowed in non-strict mode, which makes it even more confusing.
As a general rule for these situations, when a function should be created by conditions - use a function expression. Let's see how it is possible:
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/gp8fco6q/)
`ok` variable is assigned to one or another function depending on the condition. Invoking `ok()` works fine, without errors.
## 2\. Function expression
> **A function expression** is determined by a `function` keyword, followed by an optional function name, a list of parameters in a pair of parenthesis `(para1, ..., paramN)` and a pair of curly braces `{ ... }` that delimits the body code.
Some samples of the function expression:
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/kz204ynm/)
The function expression creates a function object that can be used in different situations:
- Assigned to a variable as an object `count = function(...) {...}`
- Create a method on an object `sum: function() {...}`
- Use the function as a callback `array.map(function(...) {...})`
The function expression is the working horse in JavaScript. Usually, you deal with this type of function declaration, alongside the arrow function (if you prefer short syntax and lexical context).
### 2\.1 Named function expression
A function is anonymous when it does not have a name (`name` property is an empty string `''`):
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/4tw57ubm/)
This is an anonymous function, which name is an empty string.
Sometimes the function name can be inferred. For example, when the anonymous is assigned to a variable:
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/m45pdbwh/)
The anonymous function name is `'myFunctionVar'`, because `myFunctionVar` variable name is used to infer the function name.
When the expression has the name specified, this is a **named function expression**. It has some additional properties compared to simple function expression:
- A named function is created, i.e. `name` property holds the function name
- Inside the function body a variable with the same name holds the function object
Let's use the above example, but set a name in the function expression:
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/4kgmLt8b/)
`function getNumber() {...}` is a named function expression. The variable `getNumber` is accessible within function scope, but not outside. Either way, the property `name` of the function object holds the name: `getNumber`.
### 2\.2 Favor named function expression
When a function expression `const fun = function() {}` is assigned to a variable, some engines infer the function name from this variable. However, callbacks might be passed as anonymous function expressions, without storing into variables: so the engine *cannot determine its name*.
[It is reasonable](https://ultimatecourses.com/blog/avoiding-anonymous-javascript-functions) to favor named functions to anonymous ones to gain benefits like:
- The error messages and call stacks show more detailed information when using the function names
- More comfortable debugging by reducing the number of *anonymous* stack names
- The function name says what the function does
- You can access the function inside its scope for recursive calls or detaching event listeners
## 3\. Shorthand method definition
> **Shorthand method definition** is used in a method declaration on object literals and ES2015 classes. You can define them using a function name, followed by a list of parameters in a pair of parenthesis `(para1, ..., paramN)` and a pair of curly braces `{ ... }` that delimits the body statements.
The following example uses a shorthand method definition in an object literal:
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/brhkdzca/)
`add()` and `get()` methods in `collection` object are defined using short method definition. These methods are called as usual: `collection.add(...)` and `collection.get(...)`.
The short approach of method definition has several benefits over traditional property definition with a name, colon `:` and a function expression `add: function(...) {...}`:
- A shorter syntax is easier to understand
- Shorthand method definition creates a named function, contrary to a function expression. It is useful for debugging.
The `class` syntax requires method declarations in a short form:
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/dq06y5ej/)
### 3\.1 Computed property names and methods
ECMAScript 2015 adds a nice feature: computed property names in object literals and classes.
The computed properties use a slight different syntax `[methodName]() {...}`, so the method definition looks this way:
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/5La81c07/)
`[addMethod](...) {...}` and `[getMethod](...) {...}` are shorthand method declarations with computed property names.
## 4\. Arrow function
> **An arrow function** is defined using a pair of parenthesis that contains the list of parameters `(param1, param2, ..., paramN)`, followed by a fat arrow `=>` and a pair of curly braces `{...}` that delimits the body statements.
When the arrow function has only one parameter, the pair of parentheses can be omitted. When it contains a single statement, the curly braces can be omitted too.
Let's see the arrow function basic usage:
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/16jz35w8/)
`absValue` is an arrow function that calculates the absolute value of a number.
The function declared using a fat arrow has the following properties:
- The arrow function does not create its execution context but takes it lexically (contrary to function expression or function declaration, which creates its own `this` depending on invocation)
- The arrow function is anonymous. However, the engine can infer its name from the variable holding the function
- `arguments` object is not available in the arrow function (contrary to other declaration types that provide `arguments` object). You are free to use rest parameters `(...params)`, though.
### 4\.1 Context transparency
`this` keyword is a confusing aspect of JavaScript (check [this article](https://dmitripavlutin.com/gentle-explanation-of-this-in-javascript/) for a detailed explanation of `this`).
Because functions create their execution context, often it is difficult to detect `this` value.
ECMAScript 2015 improves `this` usage by introducing the arrow function, which takes the context lexically (or simply uses `this` from the immediate outer scope). This is nice because you don't have to use `myFunc.bind(this)` or store the context `const self = this` when a function needs the enclosing context.
Let's see how `this` is accessed from the outer function:
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/40d1kq9n/)
`Numbers` class holds an array of numbers and provides a method `addNumber()` to insert new numbers.
When `addNumber()` is called without arguments, a closure is returned that allows inserting numbers. This closure is an arrow function that has `this` as `numbersObject` instance because the context is taken lexically from `addNumbers()` method.
Without the arrow function, you have to manually fix the context. It means using workarounds like `array.bind(thisVal)` method:
or store the context into a separate variable `var self = this`:
Context transparency can be used when you want to keep `this` as is, taken from the enclosing context.
### 4\.2 Short callbacks
When creating an arrow function, the parenthesis pairs and curly braces are optional for a single parameter and single body statement. This helps in creating very short callback functions.
Let's make a function that finds if an array contains `0`:
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/9pj1ukwf/)
`item => item === 0` is an arrow function that looks straightforward.
Note that nested short arrow functions are difficult to read. The convenient way to use the shortest arrow function form is a single callback (without nesting).
If necessary, use the expanded syntax of arrow functions when writing nested arrow functions. It's just easier to read.
## 5\. Generator function
The generator function in JavaScript returns a [Generator object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator). Its syntax is similar to function expression, function declaration, or method declaration, just that it requires a star character `*`.
The generator function can be declared in the following forms:
a. Function declaration form `function* <name>()`:
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/j24k8hge/)
b. Function expression form `function* ()`:
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/29hk1vo8/)
c. Shorthand method definition form `*<name>()`:
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/dmwr2a0u/)
In all 3 cases, the generator function returns the generator object `g`. Later `g` is used to generate a series of incremented numbers.
## 6\. One more thing: new Function
In JavaScript functions are first-class objects: a function is a regular object of type `function`.
The ways of the declaration described above create the same function object type. Let's see an example:
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/hqw5Lz6t/)
The function object type has a constructor: [`Function`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function).
When `Function` is invoked as a constructor `new Function(arg1, arg2, ..., argN, bodyString)`, a new function is created. The arguments `arg1, args2, ..., argN` passed to the constructor become the parameter names for the new function, and the last argument `bodyString` is used as the function body code.
Let's create a function that sums two numbers:
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/31zbad0q/)
`sumFunction` created with `Function` constructor invocation has parameters `numberA` and `numberB` and the body `return numberA + numberB`.
The functions created this way don't have access to the current scope, thus closures cannot be created. They are always created in the global scope.
One *possible* application of `new Function` is a [better way](https://twitter.com/WebReflection/status/269578376833024000) to access the global object in a browser or NodeJS script:
[Open the demo.](https://jsfiddle.net/dmitri_pavlutin/dyvgnL82/)
Remember that functions **seldom** should be declared using `new Function()`. Because the function body is evaluated on runtime, this approach inherits many `eval()` usage [problems](http://stackoverflow.com/a/86580/1894471): security risks, harder debugging, no way to apply engine optimizations, no editor auto-complete.
## 7\. In the end, which way is better?
There is no winner or loser. The decision of which declaration type to choose depends on the situation.
There are some rules however that you may follow in common situations.
If the function uses `this` from the enclosing function, the arrow function is a good solution. When the callback function has one short statement, the arrow function is a good option too, because it creates short and light code.
For a shorter syntax when declaring methods on object literals, the shorthand method declaration is preferable.
`new Function` way to declare functions normally should not be used. Mainly because it opens potential security risks, doesn't allow code auto-complete in editors, and loses the engine optimizations.
*Do you prefer arrow functions or function expressions?\!* |
| Shard | 195 (laksa) |
| Root Hash | 5311222262284501795 |
| Unparsed URL | com,dmitripavlutin!/6-ways-to-declare-javascript-functions/ s443 |