Functions
Functions are the fundamental building blocks of JavaScript programs. Functions encapsulate code designed to perform specific tasks. They are defined once but may be executed any number of times. JavaScript functions may have parameters and may compute a return value. If there is a return value, this becomes the value of the function-invocation expression. If the return is omitted, undefined is returned.
Functions - objects
Functions are objects in JavaScript.
Because functions are objects in JavaScript, they can be:
- assigned to variables
- passed to functions as parameters
- returned from functions
JavaScript functions do not require types for the parameters or result. If you mix up argument types, you only find out when something strange happens at runtime. On the flip side, you can write functions that work with arguments of multiple types, which can be convenient.
function average(x, y) {
return (x + y) / 2
}
let result = average(6,7) // result is 6.5
outputs:
But what if you pass something that isn't a number?
function average(x, y) {
return (x + y) / 2
}
let result = average('6','7')
console.log(result);
outputs:
The + becomes a concatenate and 67 is divided by 2.
Typescript: Requires types if the types cannot be inferred.
function average(x: number, y: number): number {
return (x + y) / 2;
}```
Defining functions
Functions can be defined multiple ways.
function declaration
Function declaration. Using the reserved word function, the function name , and (optional) parameters.
function funcName() {
// do something
}
function expression
Function expressions appear within the context of a larger expression or statement. The name is optional. Declare a variable and store a function in it - just like any other object.
A function declaration, declares a variable and assigns a function object to it. A function expression, does not declare a variable: it is up to you to assign the newly defined function object to a variable if you may need to refer to it again. const is recommended so you don't accidentally overwrite the function.
const square = function(num) {
return num * num;
}
square(7); // 49
// function expressions can include names
const f = function fact(x) {
if (x <= 1) return 1;
else return x*fact(x-1);
};
arrow functions
Arrow functions offer compact syntax that includes an => between the parameters and the body. Arrow functions have a compact syntax and are useful when passing a function as an argument to another function.
// or more compact
const sum = (x, y) => x + y;
-
The syntax uses an
=>to separate the function parameters from the function body. -
The function keyword is not needed as arrow functions are expressions - not statements.
-
If the body of the function is a single return statement, you can omit the return keyword, the semicolon
;, and the{ } -
An empty pair of parentheses is required if there are no arguments.
Here's an example arrow function:
const sum = (x, y) => {return x + y; };
but the code can be written more compactly as:
const sum = (x, y) => x + y;
const sayHello = (name) => `Hello, ${name}!`;
or even more compact if there is one parameter:
const polynomial = x => x * x + 2 * x + 3;
or if no parameters:
const constantFunc = () => 42;
arrow function syntax
This traditional syntax:
function () {
statements
}
can be condensed an arrow function:
() => {
statements
}
This function declaration:
function () {
return value;
}
can be expressed as an arrow function:
() => value
This function declaration:
function (a,b) {
return value;
}
can be expressed as an arrow function:
(a,b) => value
This function declaration:
const g = function(a) {
return value;
}
can be expressed as an arrow function:
const g = a => value
Arrow functions provide the parameter variables to the left of the arrow and the return value to the right.
- If there is a single parameter, you can omit the parentheses.
- If the function has no parameters, use an empty set of parentheses.
- If an arrow function is not trivial, place its body inside a block statement. Use the return keyword to return a value out of the block.
Here's the indexOf() function as a traditional function:
function indexOf(arr, value) {
for (let i in arr) {
if (arr[i] === value) return i
}
return -1
}
and now as an arrow function:
const indexOf = (arr, value) => {
for (let i in arr) {
if (arr[i] === value) return i
}
return -1
}
Functions as parameter
Functions can also be passed as a parameter. Function parameters can be:
- a function expression OR
- a function definition
For example, if we create a function expression double:
const double = function(x) { return 2*x; };
We can pass double as a parameter:
mydata.dostuff(double);
or we can simply pass an arrow function that doubles:
mydata.dostuff(x => 2*x);
Higher Order Functions
Functions as parameters let us decide our functionality on at runtime. We provide the actual value (‘argument’) when we run the function. We may not want to decide exactly what some of our functionality is until we run our function. A higher order function follows this principle; they take one or more functions as arguments and return a function as the result.
function mysteryFunc() {
return function() {
console.log("Congrats, you win!");
}
}
const myFunc = mysteryFunc();
myFunc();
Callback function
A callback function in JavaScript is a function passed as an argument to another function, intended to be executed after the completion of the outer function or after a specific event occurs.
The greet function defined on lines 1 to 4 in this example accepts a callback. When invoked, on line 10, we pass the sayGoodbye function as a parameter. The callback is executed after the console.log. Callbacks provide a way to order execution.
function greet(name, callback) {
console.log(`Hello, ${name}!`);
callback();
}
function sayGoodbye() {
console.log("Goodbye!");
}
greet("Alice", sayGoodbye); // Passing sayGoodbye as a callback
yields the following output:
Methods
Functions that are assigned to a property of an object, are known as a method of that object. When a function is invoked on an object, that object is the this value for the function.
let calculator = {
operand1: 1,
operand2: 1,
add() { // method here }
};
calculator.add(); // invoke method