Foreword
If you're completely new to functions, start here:
Intro to Functions In JS π»
Lily Misra γ» Oct 15 '20 γ» 1 min read
Overview
Functions is an incredibly deep topic for any programming language. Here, we just give some basic overview based on some of the most common βs that I receive from students.
Parameters and Arguments
When we see something like: function adder(num1, num2)
, num1
and num2
are parameters. Said parameters will be bound to arguments when we invoke/call/run the function. So, in the case of adder(1, 2)
, 1
would be bound to num1
and 2
would be bound to num2
. This binding will endure throughout the function's scope - from the opening {
to the closing {
.
Variadic Parameter Functions
Sometimes, we wish to write a function that can accept an unlimited number of arguments. We can use rest parameters ...
. This will grab all of the _arguments and bind them as an array to the parameter.
// nums will be an array.
function addManyNumbers(...nums) {
// TODO: Use 'reduce' to add up and return all the numbers
}
// Send as many arguments as you want
addManyNumbers(1, 2, 3, 4, 5)
return
If you don't include a return
in your function
, it will implicitly return undefined
. This is not generally desirable. AMAP, you should include an explicit return
.
That return
value could then be log
ged or just bound to another variable for later use.
function adder(num1, num2) {
return num1 + num2
}
const sum = adder(1, 2);
Arrow Syntax
As of ES2015/ES6+, we can save some typing. To create adder
as we had mentioned ππ½:
const adder = (num1, num2) => {
return num1 + num2
}
If our function only has 1 statement, we can rely on an implicit return
. This means we get rid of {
, }
and return
, creating a beautiful '1-liner': const adder = (num1, num2) => num1 + num2
π€.
Default Parameters
We can give our parameters default values such that if we invoke the function without explicitly passing in a value, the default will be used.
Above, we first invoke w/o any arguments. So, both default values, 1
and 2
were used. In the second case, we did pass in our own value for the first parameter, 5
. Only the second parameter used its default value, 2
.
Methods
A method is nothing but a function that is scoped inside another object literal.
There are many built in methods that we use all of the time. For example, console.log()
, where log
is a function 'scoped' to the console
object.
This can lead us to the basis of JS's prototypal OOP features - a topic for another post! π
Callback Functions
JS functions are first class π. Anything we can do with other data types, we can do with functions. We can pass functions as arguments into other functions - callback functions. We can also return functions from other functions.
Callbacks are great for 'event-driven' operations. For example, DOM interactions such as handling "click"
s: addEventListener("click", () => {
.
There is a function that gets 'called back' whenever the browser notifies JS of a 'click event.'
Closures - Returning a Function
In this pattern, we are utilizing a function factory π. It's a function that returns other functions. Along the way, the argument passed in to create that 'returned function' becomes enclosed, with a bound reference that persists as long as that 'created function' persists.
Closures is a tough concept to learn about. The below example usually does the trick in my classes to illustrate the pattern at least:
'Pure' Functions
This too could be a whole separate topic, but generally, 'pure functions' are those that:
i) given the same input always return the same output
ii) Have explicit return
iii) Don't depend on anything outside of their scope.
I liken these to 'copy/paste' functions. If they are written correctly, these functions could be copied and pasted into any codebase and invoked w/o any issue. They are 'independent' functions.'
Don't overthink π§ this. const adder = (num1, num2) => num1 + num2
is a pure function. We can copy/paste it anywhere and it doesn't care about anything outside of its scope. It just sits around until we send it 2 numbers. Then it does its job w/o touching anything else in our program ππ½.
πΆ about some 'Best Practices' and 'Clean Code'
I'm going to highlight a couple of the recommendations given here:
- Functions should do 1 thing. If you can't clearly name your function, then chances are it's doing too much. Regarding naming, I personally try to start the name with a verb to make it clear that it's a function and that it 'does' something.
- Functions should avoid taking more than 2 parameters. If you need more, rely on object destructuring. Here's an example:
We invoke the function by passing in an object literal as the argument. This is then destructured. You can see that we can still provide default values as previously discussed ππ½.
You might also notice that our parameter as a whole has a default value, {} π€. I'll leave it as an exercise for you to deduce why we might want that. Hint: Try ππ½ββοΈ the function w/o any arguments with and w/o that {}
default.
There's a lot more that could be said on this topic, but after a while too much theory is counterproductive. You should go practice writing code π©π½βπ» while keeping these things in mind π§ . Then, come back and post your βs for discussion. You have more than enough to start writing βοΈ your own functions.
Top comments (0)