tldr;
Every JavaScript application uses functions. In this blog post we’ll go over the basics of functions and arrow functions, providing default parameters to functions, passing named parameters to functions, and using the rest parameters in functions. By the end of this blog post, you should be comfortable with each of these parts of dealing with JavaScript functions. Everything we cover in this blog post can be used in modern browsers today.
Named Functions
Let’s start with the most simple way to write a function. Here’s an example:
functionmyFunction(arg1){// Do something}
Each named function starts with thefunction
keyword. After that comes the name of the function. This is how you’ll reference and call the function later on. From the example above, the name would bemyFunction
. After the function name comes the argument list, enclosed in parentheses. The arguments, also called parameters, are optional but the parentheses are not. Then the function body starts and ends with curly braces. Inside the body of the function is where you’ll do your work. To call a function, you use its name, open parentheses, the list of arguments, and close parentheses.
myFunction('hello');
Another way you can create a function is by assigning an anonymous function to a variable. An anonymous function is a normal function but it doesn’t have a name. You would only use these as callbacks or by assigning them to a variable. Let’s look at an example of assigning an anonymous function to a variable.
constmyFunction=function(arg1){// Do something}myFunction();
You can call it in the same way too, as seen above. These are both valid ways of creating functions. In my experience, named functions are more common than assigning an anonymous function to a variable.
You can also have functions as attributes on objects. These functions have a special name: methods. It’s really the same thing though, and you can call it a method or a function. Everyone will know what you’re talking about. Here’s an example of a method and how to use it:
functionsayHi(){console.log(`Hi my name is${this.name}.`);}constperson={name:'Preston Lamb',sayHi}person.sayHi();// orconstperson={name:'Preston Lamb',sayHi:function(){console.log(`Hi my name is${this.name}.`);}}person.sayHi();// orconstperson={name:'Preston Lamb',sayHi(){console.log(`Hi my name is${this.name}.`)}}person.sayHi()
All three of these examples have the same result and are valid ways to add methods to an object. We’ll talk about arrow functions as methods next.
Arrow Functions
Another type of function that’s common in JavaScript is a lambda function, or arrow function as it’s more commonly known. Arrow functions are especially great when being used as a callback, but you don’t only have to use them as callbacks. They’re quick to write and easy to use. Let’s take a look at how you can use arrow functions.
constsayHi=()=>console.log('Hi!');sayHi();// Hi!constarr=['Item 1','Item 2'];arr.forEach((item)=>console.log(item));// Item 1 Item 2constperson={name:'Preston Lamb',doSomething:()=>console.log('Does something');}person.doSomething();// Does something
Arrow functions do not have their own context, so in the last example they have no access to
this
. To learn more, referencemy article on thethis
keyword in JavaScript.
Arrow functions are great, and I normally reach for them mainly as callbacks. I don’t personally use them as the first example above, although it’s perfectly valid. If you don’t need any specific context in the function, an arrow function is a great option.
Providing Default Parameters to Functions
Another great feature of functions in ES6 is default function parameters. Default parameters makes it so that a parameter value is initialized with some value, but this initialized value will be overwritten by whatever is passed in to the function. This makes it so that there’s always some value in the parameter of a function; they won’t beundefined
unless explicitly passed that way. Let’s look at an example where this would be helpful.
functiondivide(top,bottom){console.log(top/bottom);}divide(5);// NaN
Here we have adivide
function that takes two numbers and returns the top divided by the bottom. When we call it in the above manner, without the second parameter, the result isNaN
. That’s because thebottom
parameter isundefined
since nothing was passed in to the function. Then maybe we forget to check what type the return value of this function is elsewhere in our code, and we assume it’ll always be a number. But in this case we’d get an error elsewhere becauseNaN
is not a number. So to prevent the error, we have to do checks on the result anywhere we may call the function. It’d be best if we never ran in to this problem though, right? So let’s provide some default parameters to this function.
functiondivide(top,bottom=1){console.log(top/bottom);}divide(5);// 5
This time we call the function in the same way, but because we’ve provided a default parameter to the function for thebottom
parameter, its value will always be 1 if nothing is passed in. So instead of gettingNaN
, we get5
for our answer here.
This example is a little contrived, but here’s another example of something that I’ve run into in my job before. Let’s say we have a function that creates a new instance of an object with several attributes. Sometimes we want to give some starting values to the object, but other times we don’t. We can do this simply with default parameters.
functiondog(startingValues={}){constdogObject={name:startingValues.name||'',breed:startingValues.breed||''};returndogObject;}constduke=dog();console.log(duke);// { name: '', breed: '' }constmax=dog({name:'Max'});console.log(max);// { name: 'Max', breed: '' }
Without the default parameters, if we didn’t pass an object to thedog
function, we would get an error:cannot read property name of undefined
. In this case, default parameters work perfectly to prevent us from having errors in our application.
You can have multiple default parameters in a function. Let’s say arguments two and three both have default parameters. If you want to use the default parameter for the second argument, but pass the third argument, you’re out of luck. You’d have to pass something as the second argument, even if it was
null
.
Named Parameters to Functions
Another convenient feature of parameters in ES6 functions is named parameters. Sometimes the parameter list of a function gets really long, and it can be hard to know what each parameter should be. If you wrote the function, you might remember. But only when you first wrote the function. Then each time you come back to it you’ll have to look again and try to remember what each does. Or, you could use named parameters. To use named parameters, all you’ll need to do is pass a single object to the function instead of multiple parameters. It’s similar to what we did in the last section. But instead of naming the variable (like we did abovestartingValues
) we will have access to each of the attributes of the object as variables inside the function. Let’s take a look at this. We’ll first show an example without named parameters, and an example with.
functiondogInfo(name,breed,age,foodPreference,likesToWalk){return`The dog's name is${name} and it is a${breed}. It's age is${age}, and it likes to eat${foodPreference}. It${likesToWalk?'does':'does not'} like to walk.`;}dogInfo('Duke','Labradoodle','3 years','anything',true);
If we need to call thisdogInfo
function, we need to remember each one of these parameters, and more importantly the order has to be correct each time. Otherwise we’re not going to get the result we’re looking for. And looking at just the function above, what do some of those parameters actually mean? If I hadn’t written the function, I wouldn’t know what thetrue
was for. Or theanything
string. It can be really confusing, especially for other developers who look at your code. Now let’s try it with named parameters.
functiondogInfo({name,breed,age,foodPreference,likesToWalk}){return`The dog's name is${name} and it is a${breed}. It's age is${age}, and it likes to eat${foodPreference}. It${likesToWalk?'does':'does not'} like to walk.`;}dogInfo({name:'Duke',breed:'Labradoodle',age:'3 years',likesToWalk:true,foodPreference:'anything'});
This time, it’s very clear what each item is that we’re passing to the function. The object we pass in has the attribute of each right next to it. The other thing is that in this manner there is no order for the attributes on the object. No matter how you order them, it’s still going to work. That’s so much better than the first function! Also, your IDE should give you help in knowing what you should pass as well. Let’s now combine named parameters and default parameters.
functiondogInfo({name='Your Dog',breed='unknown',age,foodPreference,likesToWalk=true}={}){return`The dog's name is${name} and it is a${breed}. It's age is${age}, and it likes to eat${foodPreference}. It${likesToWalk?'does':'does not'} like to walk.`;}dogInfo({age:'3 years',foodPreference:'anything'});
This time we only passed in theage
attribute and thefoodPreference
, but due to default parameters we didn’t have any problems missing parameters, and we didn’t need to passnull
as a parameter or anything like that. With named and default parameters, we can pass just the values we want and leave out the rest. This is really nice and really convenient.
Rest Parameters
The last thing we’ll talk about is therest
parameters option in a function. What this allows you to do is to name a certain number of parameters to the function, and then catch the rest of them in an array. Let’s look at an example of this.
functionaddition(setName,...numbers){consttotal=numbers.reduce((prev,next)=>prev+=next,0);return`Total of${setName}:${total}`;}constresult=addition('years',1,2,3,4);console.log(result);// Total of years: 10
What this function does is takes a parameter that is calledsetName
, which is the name of the set of numbers we’re passing it. Then we capture the rest of the arguments passed to the function in thenumbers
array. It could be 0 to many arguments that are in thatrest
parameter. This is really convenient for when your function needs at least N arguments, but can use as many are as passed.
Now, thisnumbers
parameter is different than the built inarguments
attribute of a function. The biggest is thatarguments
includes all the arguments or parameters passed to a function. Therest
parameter only includes all the parameters that weren’t named. The next big difference is that therest
parameter is actually an array.arguments
is array-like, but you can’t use array methods (likeforEach
orreduce
) onarguments
. So you can usearguments
, but it is different than arest
parameter.
Conclusion
Knowing all the ways to declare functions and use functions and parameters will allow you to write the most efficient applications possible. They’ll also be more user friendly, in the case of named parameters for example. A little bit of practice and a little bit of learning will make these things come more easily and second nature to you.
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse