Front End Developers-Lab
(JS) JavaScript
Four Ways to Create a Function in JavaScript
There are four ways a function can be created in JavaScript.
A function as a statement
A function as an expression
A function as an arrow function
A function created using the Function constructor
All four ways of function creation have distinct features such as an arrow function that does not have its own this object, a function statement that is hoisted on the top of the execution context, and a function expression that can be immediately invoked without creating a separate scope. Having a good understanding of various characteristics of different types of JavaScript functions is useful to write better code. This Jsxcode explains these functions.
A function as a statement
A function as an expression
A function as an arrow function
A function created using the Function constructor
All four ways of function creation have distinct features such as an arrow function that does not have its own this object, a function statement that is hoisted on the top of the execution context, and a function expression that can be immediately invoked without creating a separate scope. Having a good understanding of various characteristics of different types of JavaScript functions is useful to write better code. This Jsxcode explains these functions.
1- A Function as a Statement
A function as a statement can be created as shown the following
code example:
code example:
code example:
code example:
In a function statement, primitive parameters are passed as a value, and non-primitive parameters such as objects and arrays are passed as a reference.
code example:
function Add(num1,num2){ let sum = num1+ num2; return sum; } let result = Add(7,8); console.log(res); // 15A function statement starts with the function keyword. It can return a primitive type value, object, or another function. For example, a function statement can return an object as shown in the following code example:
code example:
function getProduct(){ let product = { Id:1, Title:'Book', Price: 30 }; return product; } let p1 = getProduct(); console.log(p1); // prints product objectThe main characteristic of a function statement is it is hoisted at the top of the execution context. Therefore, you can call a function statement before it is declared, as shown in the following code example:
code example:
let result = Add(7,8); console.log(result); // 15 // .... other codes function Add(num1,num2){ let sum = num1+ num2; return sum; }As you see, that Add function is called before it is created, and this is possible because a function statement is hoisted at the top of the execution context. A function statement is hoisted at the top of the execution context. So, it can be invoked before it is created. In a function statement, you can pass primitive values as either parameters or non-primitive values, such as an object or array. The primitive parameters are passed as a value, and the non-primitive values are passed as a reference. So, if you pass an object to a function statement and the function changes the object’s properties, that change is visible outside the function, as shown in the following code example:
code example:
function updateProduct(product){ product.Title = 'Updated Book'; } let product = { Id:1, Title:'Book', Price: 30 }; console.log(product.Title); // Book updateProduct(product); console.log(product.Title); // Updated BookIn the above code, JavaScript updates the Title of the product object. However, if you pass a string, number, or Boolean parameters in the function, it won’t be reflected globally.
In a function statement, primitive parameters are passed as a value, and non-primitive parameters such as objects and arrays are passed as a reference.
2- A Function as an Expression
A function as an expression can be created as shown in the following
code example:
code example:
A function expression can be created without a name, whereas a function statement must have a name
A function expression is not hoisted on the top of the execution context, whereas a function statement is hoisted at the top of the execution context Since a function expression is not hoisted at the top of the execution context, calling the function before it is created throws ReferenceError, as shown in the following
code example:
A function expression is not hoisted at the top of the execution context, so it cannot be invoked before it is created
A function expression is not hoisted at the top of the execution context. So, it cannot be invoked before it is created. One other important feature of a function expression is that it can be immediately invoked as soon as it is defined, which is also known as Immediately Invoked Function Expression:
code example:
let add = function a(num1,num2){ let sum = num1+ num2; return sum; } let res = add(8,9); console.log(res);// 17In a function expression, you assign a function to a variable. A function expression can also be created as anonymous without a name, as shown in the following
code example:
let add = function (num1,num2){ let sum = num1+ num2; return sum; } let res = add(8,9); console.log(res);// 17The name of the function expression is local to the function body and very useful for recursions or any scenario in which you need to refer to the function inside the function body. You can write a factorial function by using function expression name:
var Calculator = { factoriral : function fact(n){ if(n<=1){ return 1; } return n*fact(n-1); } } let result = Calculator.factoriral(7); console.log(result); // 5040The main differences between a function statement and a function expression are:
A function expression can be created without a name, whereas a function statement must have a name
A function expression is not hoisted on the top of the execution context, whereas a function statement is hoisted at the top of the execution context Since a function expression is not hoisted at the top of the execution context, calling the function before it is created throws ReferenceError, as shown in the following
code example:
let res = add(8,9); console.log(res); // ReferenceError : add is not a function //output: Error: Cannot access 'add' before initialization let add = function (num1,num2){ let sum = num1+ num2; return sum; }So, you can summarize the hoisting difference as: A function statement is hoisted at the top of the execution context, so it can be invoked before it is created
A function expression is not hoisted at the top of the execution context, so it cannot be invoked before it is created
A function expression is not hoisted at the top of the execution context. So, it cannot be invoked before it is created. One other important feature of a function expression is that it can be immediately invoked as soon as it is defined, which is also known as Immediately Invoked Function Expression:
let add = function (num1,num2){ let sum = num1+ num2; return sum; }(8,9); console.log(add); // 17On the other hand, a function statement cannot be immediately invoked as soon as it is defined without creating a separate scope, as shown in the following code example.
(function add(num1,num2){ let sum = num1+num2; console.log(sum); //17 })(8,9);
3- An Arrow Function
The arrow functions were introduced in ECMA 2015 with the main purpose of giving a shorter syntax to a function expression. Besides providing shorter syntax, which increases the readability of the code, it does not have its own value of the this object. The value of this object inside an arrow function is inherited from the enclosing scope.
You can write an arrow function to add two numbers as shown in the next code example.
The Array constructor method has three different syntaxes. If we call the constructor with two or more arguments, it declares an array with array elements also initialized. If we provide only one argument to the Array constructor, it refers to the length of the new array with, elements not initialized. Lastly, the constructor without any argument creates an array with its length set to zero with elements not initialized.
Let's see some examples.
Parameters should be passed in a small bracket
If there is only one parameter, then the bracket is optional
If there is no parameter, then it must have a small empty bracket
If there is only a single expression in the function body, then using
parentheses is optional
If there is only a single expression in the function body, then using the return statement is optional
You can apply the above syntax rules to create arrow functions, as shown in the following code example.
It supports the rest parameters
It supports the default parameters
It does not have arguments object
It does not have its own this object
It cannot be used as a constructor
The value of this object inside an arrow function is inherited from the enclosing scope. To understand it in a better way, consider the following code example:
But, if you refactor the koo function as an arrow function, then instead of having its own this object, it inherits it from the enclosing scope, as shown in the next code example.
You can write an arrow function to add two numbers as shown in the next code example.
(function add(num1,num2){ let sum = num1+num2; console.log(sum); //17 })(8,9);2. Using The Array Constructor.
The Array constructor method has three different syntaxes. If we call the constructor with two or more arguments, it declares an array with array elements also initialized. If we provide only one argument to the Array constructor, it refers to the length of the new array with, elements not initialized. Lastly, the constructor without any argument creates an array with its length set to zero with elements not initialized.
Let's see some examples.
var add = (num1, num2)=> num1+num2; let res = add(5,2); console.log(res); // 7Some syntax rules for an arrow function are:
Parameters should be passed in a small bracket
If there is only one parameter, then the bracket is optional
If there is no parameter, then it must have a small empty bracket
If there is only a single expression in the function body, then using
parentheses is optional
If there is only a single expression in the function body, then using the return statement is optional
You can apply the above syntax rules to create arrow functions, as shown in the following code example.
// More the one parameters and only one expression var add = (num1, num2)=> num1+num2; // No parameters and no return statment let greet = ()=> console.log('hey'); // More than one paramter and more than one expression in body var divide = (num1,num2)=>{ if(num2 ==0){ return 'can not divide'; } else { return num1 / num2; } }To return an object from an arrow function, you can either use a return statement or a slightly different syntax of enclosing the object in a small bracket, as shown in the following example:
let product = (title,price)=>({ title:title, price : price }) let p1 = product('pen',100); console.log(p1);Some other important features of an arrow function are:
It supports the rest parameters
It supports the default parameters
It does not have arguments object
It does not have its own this object
It cannot be used as a constructor
The value of this object inside an arrow function is inherited from the enclosing scope. To understand it in a better way, consider the following code example:
let Product = { Title :'Pen', Price : 100 } function foo(){ console.log(this); // Product object function koo(){ console.log(this); // global object } koo(); } foo.call(Product);The function foo is called indirectly using the call() method to pass the Product object as the value of this inside it. And since the function koo is called using the function invocation pattern, the value of this object for it is the global object. So, even though koo is an internal function of foo, it has its own value of this object.
But, if you refactor the koo function as an arrow function, then instead of having its own this object, it inherits it from the enclosing scope, as shown in the next code example.
let Product = { Title :'Pen', Price : 100 } function foo(){ let that = this; console.log(this); // Product object var koo = ()=> console.log(this); koo(); } foo.call(Product);The other restriction on arrow functions is that they cannot be used as constructors, so the following code example throws an exception.
var Product = (Title,Price)=>{ return { Title:Title, Price: Price } } let p1 = new Product('Pen',200); // Error Product is not a constructor
4- Using Function Constructor
A function can be dynamically created using the Function constructor, but it suffers from security and performance issues and is not advisable to use.
You can create a function using the Function constructor as shown in the following example.
Summary
In this article you learned about various ways of creating a function and their characteristics – for example, a function statement is hoisted at the top of the execution context, a function expression is not hoisted and can be created without a name, and an arrow function does not have its own this object.
I hope you found the article useful. Thanks for reading.
You can create a function using the Function constructor as shown in the following example.
var add =Function ('num1','num2','return num1+num2'); let res = add (7,8); console.log(res); // 15In the Function constructor, you pass parameters and function body as a string. The function created with the Function constructor is always created in the global scope.
Summary
In this article you learned about various ways of creating a function and their characteristics – for example, a function statement is hoisted at the top of the execution context, a function expression is not hoisted and can be created without a name, and an arrow function does not have its own this object.
I hope you found the article useful. Thanks for reading.