Another handy feature that has been existing in most advanced programming languages but added into JavaScript by ES-6 enhancements is the concept of default arguments.
We already discussed a lot about functions and arguments in previous article of this series here and we have already seen that you can pass any number of parameters to a function which might be accepting one , two or n number or parameters.
We already know that a function can have either named arguments which can hold the values passed to a function or arguments object containing all the arguments passed to a function.
Let’s try to handle default values for parameters in they are not passed explicitly by developer but required by program to run.
<script type="text/javascript"> function handleDefaultValues(i , j , k){ j = (typeof j !== "undefined") ? j : 10; k = (typeof k !== "undefined") ? k : 10; return i+j+k; } handleDefaultValues(1); handleDefaultValues(1,2); handleDefaultValues(1,2,3); </script>
style="display:block; text-align:center;"
data-ad-format="fluid"
data-ad-layout="in-article"
data-ad-client="ca-pub-5021110436373536"
data-ad-slot="9215486331">
Output:
21 //Default value taken for j and k
13 //Default value taken for k
6
So, as you can see we are still able to achieve what we need but additional programming is required to cater our scenario.
ES-6 has simplified the default value handling as follows
<script type="text/javascript"> function handleDefaultValues(i , j =10 , k =10){ console.log( i + j + k ); } handleDefaultValues(1); handleDefaultValues(1,2); handleDefaultValues(1,2,3); </script>
style="display:block; text-align:center;"
data-ad-format="fluid"
data-ad-layout="in-article"
data-ad-client="ca-pub-5021110436373536"
data-ad-slot="9215486331">
Output:
21 //Default value taken for j and k
13 //Default value taken for k
6
Best part about default argument values is that you can assign not only primitive types but rather values of preceding arguments as well as functions as shown below
<script type="text/javascript"> function getDefault(){ return 10; } function handleDefaultValues(i , j = i , k =getDefault()){ console.log( i + j + k ); } handleDefaultValues(1); handleDefaultValues(1,2); handleDefaultValues(1,2,3); </script>
style="display:block; text-align:center;"
data-ad-format="fluid"
data-ad-layout="in-article"
data-ad-client="ca-pub-5021110436373536"
data-ad-slot="9215486331">
Output:
12 //i.e. i=1, j =1, k =10
13 //i.e. i=1, j =2, k =10
6 //i.e. i=1, j =1, k =3
So, our learning till now:
a.) It’s not mandatory to pass all parameters to a function. The parameters which are not passed are assigned a default value of undefined
b.) We can also provide default values to function arguments
c.) We can assign either primitive values or functions to arguments
d.) We can get all parameters passed to a function via arguments object
Rest Parameter
Let’s see how we can get rest of the parameters apart from names ones
<script type="text/javascript"> function getDefault(){ return 10; } function handleDefaultValues(i , j = i , k =getDefault()){ console.log( i + j + k ); for (var index = 3; index < arguments.length; index++) { console.log(arguments[index]); } } handleDefaultValues(1,2,3,4,5,6); </script>
style="display:block; text-align:center;"
data-ad-format="fluid"
data-ad-layout="in-article"
data-ad-client="ca-pub-5021110436373536"
data-ad-slot="9215486331">
As you can see from above example, we have got the rest of the values passed to a function using arguments indexing. This is not a robust way of dealing with rest parameters as if you somehow refactor the method later on by adding and removing parameters you might be accessing unexpected values rather than ones you actually want.
We need to simplify code and avoid looping and that’s where ES-6 new Rest operator makes life easier. Let’s try to understand using below example.
<script type="text/javascript"> function getDefault(){ return 10; } function handleDefaultValues(i , j = i , k =getDefault(),...addresses){ console.log( i + j + k ); console.log(addresses); } handleDefaultValues(1,2,3,"Address 1","Address 2" , "Address 3"); </script>
style="display:block; text-align:center;"
data-ad-format="fluid"
data-ad-layout="in-article"
data-ad-client="ca-pub-5021110436373536"
data-ad-slot="9215486331">
Output:
6
[object Array][“Address 1″, “Address 2″, “Address 3″]
Rest arguments are array type and contain rest of the parameters apart from named ones. There are however, certain restrictions to usage of rest parameters:
a.) Rest parameters must be the last parameters
b.) Rest parameters cannot be used in property setters
Spread Operator
With Rest parameter, we kinda created a catch all variable for rest of the parameters that are passed to a function apart from the named arguments defined in function signature. It really simplifies lot of things for e.g consider below scenario where we concatenate 2 arrays
<script type="text/javascript"> var array1 = [1,2,3]; var array2 = [4,5,6]; array1 = array1.concat(array2); for (var index = 0; index < array1.length; index++) { console.log(array1[index]); } </script>
style="display:block; text-align:center;"
data-ad-format="fluid"
data-ad-layout="in-article"
data-ad-client="ca-pub-5021110436373536"
data-ad-slot="9215486331">
Output:
1
2
3
4
5
6
We can achieve similar behavior using spread operator (…) as below. Spread operator can be used to split an array or string
<script type="text/javascript"> var array1 = [1,2,3]; var array2 = [4,5,6]; array1 = [...array1, ...array2]; for (var index = 0; index < array1.length; index++) { console.log(array1[index]); } var someString= "THIS"; var charArray = [...someString]; for (var index = 0; index < charArray.length; index++) { console.log(charArray[index]); } </script>
style="display:block; text-align:center;"
data-ad-format="fluid"
data-ad-layout="in-article"
data-ad-client="ca-pub-5021110436373536"
data-ad-slot="9215486331">
Output:
1
2
3
4
5
6
T
H
I
S