In JS functions are First-class functions because they are treated as any other variable. Remember that functions are objects.
- We can assign a function to a variable
- We can pass a function as an argument
- A function can return a function
When we call a function the first thing that happens is that a new execution context is created with a thread of execution (line by line) and a space in memory for storage. Whatever we store in memory in this local scope (aka, the context of the function) will be available JUST inside this context.
function sayHi() {
console.log('Hi');
}
sayHi(); // Hiconst sayHi = function() {
console.log('Hi');
}
sayHi(); // HiThe main difference between function declaration and function expression is that WE CAN call the function defined with function declaration before its definition.
This is because JS engine moves all the function declarations to the top. This is called hoisting.
You can see how sayHi() is hoisted.
sayHi(); // Hi
function sayHi() {
console.log('Hi');
}Quick note:
- If you use a name, like
const hi = function sayHi() {}it is a named function expression. - If not, like
const hi = function() {}it is an anonymous function expression.
The less parameters a function has, the better. So we should have default values in our functions.
function Person(name, age) {
this.name = name;
this.age = age;
// these are default properties hen we are creating the Person object
this.friends = [];
this.hobbies = [];
this.isAlive = true;
}
const peter = new Person('Peter', 30);
console.log(peter);
// Person {
// name: 'Peter',
// age: 30,
// friends: [],
// hobbies: [],
// isAlive: true,
// __proto__: { constructor: ƒ Person() }
// }function sayHi(name = 'user') {
console.log(`Hi ${name}`);
}
sayHi();
sayHi('Peter');
// 'Hi user'
// 'Hi Peter'We can have functions with a varying number of parameters...
- Using the rest operator (
parameter1, parameter2, ...args) We will be looping through the args array.
function printNames(...args) {
for (let element of args) {
console.log(element)
}
}
printNames('Peter', 'Paul', 'Lora');
// 'Peter'
// 'Paul'
// 'Lora'- Accessing the
argumentobject.
function printNames() {
console.log(arguments);
}
printNames('Peter', 'Paul', 'Lora');
// {
// '0': 'Peter',
// '1': 'Paul',
// '2': 'Lora',
// length: 3,
// callee: ƒ printNames(),
// __proto__: {
// // ...
// }
// }Loop through the arguments keys:
function printNames() {
for (let key in arguments) {
console.log(arguments[key])
}
}
printNames('Peter', 'Paul', 'Lora');
// 'Peter'
// 'Paul'
// 'Lora'Remember the difference between parameters and arguments
In the example...
coloris aparameterof the function printColor()blackis anargument
function printColor(color) {
console.log(color);
}
printColor('black');A function that takes a function as argument or returns a function and can be assigned as a value to a variable.
More info: https://developer.mozilla.org/en-US/docs/Glossary/First-class_Function
function performMathOperation(num1, num2, operation) {
return operation(num1, num2);
}
function addition(num1, num2) {
return num1 + num2;
}
function subtraction(num1, num2) {
return num1 - num2;
}
const add = performMathOperation(1, 1, addition);
console.log(add); // 2
const subtract = performMathOperation(1, 1, subtraction);
console.log(subtract); // 0Note: In the previous example performMathOperation() is a HOF and addition() is a callback function.