FIRST CLASS FUNCTION

JS

In this post we will talk about the fundamental characteristics of Javascript functions. We will talk about very important concepts such as abstraction, encapsulation which was used in ES5 called IIFE, the keyword this etc.

Definizione
First Class Object

Translating this definition with regards to JS functions it means that everything we can do with strings numbers etc. we can do it with functions. Just as we can assign a variable to a number, a string etc. so we can assign that variable to a function. Let’s see a code example to clarify these concepts.

Copy to Clipboard

FUNCTIONS AND ABSTRACTION

Let’s see what is meant by abstraction.

DEFINITION

Astrazione

Concrete examples will help us.

Copy to Clipboard

IIFE AND MODULE PATTERNS

IIFE was used in ES5 to implement a module pattern. A pattern is a model that defines the resolution of a given problem. Thanks to the IIFE, a confidential context is created outside the global space. Thus encapsulating the code without the possibility of pollution from the outside. Analyze the code shown to understand these topics.

Copy to Clipboard

CONSTRUCTOR FUNCTION

Objects in JS can be created in several ways. Literal syntax, keyword new. A constructor function is a regular function but with two conventions. The function must start with an uppercase letter and must be preceded by the new keyword. In this case an object is created which inherits properties and methods from its prototype. Let’s try to understand from the reported code how the creation of an object with new works.

Copy to Clipboard

THE KEYWORD THIS

The constructor functions produce objects, define common properties defined within the prototype object, and define other properties with this that each object will have its own copy of. Let’s analyze the code to better understand the topic.

Copy to Clipboard

PURE AND IMPURE FUNCTIONS

funzioni pure e impure
funzione deterministica

Pure and impure functions are a fundamental concept in procedural programming. A function that takes parameters as input and always returns the same output is called a deterministic function.

funzione deterministica
funzione pura

Being there the console.log is not yet a pure function as it can produce side effects in the outside world. To be pure, a function must not produce side effects. console.log displays information and this is a side effect. A pure function simplifies code maintenance and debugging.

FURTHER INFORMATION

JavaScript functions are defined with the function keyword. You can use a function declaration or a function expression.

DECLARATION OF FUNCTION

Earlier in this tutorial, you learned that functions are declared with the following syntax:

function functionName(parameters) {
  // code to be executed
}

The declared functions are not executed immediately. They are “saved for later use” and will be executed later when invoked (called).

function myFunction(a, b) {
  return a * b;
}

Semicolons are used to separate executable JavaScript statements. Since a function declaration is not an executable statement, it is not common to end it with a semicolon.

EXPRESSIONS OF FUNCTIONS

A JavaScript function can also be defined using an expression. A function expression can be stored in a variable:

const x = function (a, b) {return a * b};

After a function expression has been stored in a variable, the variable can be used as a function:

const x = function (a, b) {return a * b};
let z = x(4, 3);   //output 12

The above function is actually an anonymous function (an unnamed function). The functions stored in the variables do not require functions. They are always called up (calls) using the name of the variable. The above ends with a point and comma because it is part of an executable instruction.

THE FUNCTION() CONSTRUCTOR

As you saw in the previous examples, the JavaScript functions are defined with the Function keyword. The functions can also be defined with an integrated JavaScript functions manufacturer called Function().

const myFunctionnew Function(“a”, “b”, “return a * b”);

let x = myFunction(4, 3);  //output 12

Actually it is not necessary to use the function constructor. The example above is the same as writing:

const myFunctionfunction (a, b) {return a * b};

let x = myFunction(4, 3);

Most of the time, you can avoid using the new keyword in JavaScript.

HOISTING OF FUNCTIONS

Hoisting is JavaScript’s default behavior to move declarations to the start of the current scope. Lifting applies to variable declarations and function declarations. For this reason, JavaScript functions can be called before being declared:

myFunction(5);

function myFunction(y) {
  return y * y;
}

AUTO-INVOCATIVE FUNCTIONS

Function expressions can be “self-invoked”. An expression that is called automatically is called (started) automatically, without being called. Function expressions will be executed automatically if the expression is followed by(). It is not possible to automatically invoke a function declaration. You need to add parentheses around the function to indicate that it is a function expression:

(function () {
  let x = “Hello!!”;  // I will invoke myself
})();

FUNCTIONS CAN BE USED AS VALUES

function myFunction(a, b) {
  return a * b;
}

let x = myFunction(4, 3);  // x=12

JavaScript functions can be used in expressions:

function myFunction(a, b) {
  return a * b;
}
let x = myFunction(4, 3) * 2;  // x=24

FUNCTIONS ARE OBJECTS

The typeof operator in JavaScript returns “function” for functions. However, JavaScript functions can best be described as objects. JavaScript functions have both properties and methods. The arguments.length property returns the number of arguments received when the function was invoked:

function myFunction(a, b) {
  return arguments.length;
}

The Tostring() method returns the function as a string:

function myFunction(a, b) {
  return a * b;
}

let text = myFunction.toString();

//return function myFunction(a, b) { return a * b; }

DEEPENING AI

In JavaScript, constructor functions, the concept of prototype objects, the keyword new, and the keyword this are fundamental concepts for creating and managing objects. Let’s look at each of these concepts in detail:

1. Constructor Function.

A constructor function is a special type of function that is used to create new objects. When a function is used as a constructor, it creates a new object and sets it as the context (this) within the function. Constructor functions in JavaScript usually begin with a capital letter, by convention, to differentiate them from normal functions.

Example of a constructor function:

function Persona(nome, cognome) {
     this.nome = nome;
     this.cognome = cognome;
}

const persona1 = new Persona(‘Mario‘, ‘Rossi‘);
console.log(persona1.nome); // Output: Mario

In this example, the Persona function acts as a constructor. Using the keyword new, it creates a new object persona1, with the properties nome and cognome.

2. Object Prototype.

Every object in JavaScript has a property called prototype that allows methods and properties to be shared among all instances created by a constructor function. This mechanism is an integral part of JavaScript’s prototype-based model. Objects created by a constructor function can inherit the properties and methods defined in the object’s prototype.

Example:

Persona.prototype.saluta = function() {
     console.log(`Ciao, sono ${this.nome} ${this.cognome}`);
};

persona1.saluta(); // Output: Ciao, sono Mario Rossi

In this example, the saluta method has been added to the prototype of the Persona constructor function. Now all instances of the constructor function will have access to this method.

3. The new keyword

The new keyword is used to create a new instance of an object using a constructor function. When new is used:

-A new empty object is created.

-The context (this) within the constructor function is assigned to the newly created object.

-If the function does not explicitly return an object, the newly created object is returned automatically.

Example:

const persona2 = new Persona(‘Luigi‘, ‘Verdi‘);
console.log(persona2.nome); // Output: Luigi

4. The keyword this

The keyword this in JavaScript refers to the context in which a function is called. When this is used within a constructor function, it refers to the object that was just created. The value of this can change depending on how the function is called.

Example:

function MostraNome() {
    console.log(this.nome);
}

const persona3 = new Persona(‘Franco‘, ‘Bianchi‘);
MostraNome.call(persona3); // Output: Franco

In this example, the call() method sets the context of this in MostraNome to the persona3 object, allowing access to the nome property.

Summary:

-Constructor Function: A function used to create new objects, which is invoked with the keyword new.

-Prototype Objects: A mechanism that allows methods and properties to be shared among all instances of an object.

-Keyword new: Creates a new object based on a constructor function.

-Keyword this: Refers to the current object or context in which a function is called.

In JavaScript, functions are considered first-class citizens (or “first-class citizens”) and can be used as abstraction tools. This concept is fundamental to understanding the flexibility and power of the JavaScript language. Let us look at both concepts in detail:

Functions as First-Class Citizens.

In many programming languages, including more modern versions of JavaScript, functions are treated as first-class objects. This means that functions can be:

1. Assigned to a variable,

2. Passed as arguments to another function,

3. Returned by another function,

4. Saved in data structures such as arrays or objects,

5. Be properties of an object (methods).

Being first-class citizens means that functions in JavaScript are treated like any other value (such as strings, numbers, objects, etc.), and can be manipulated dynamically at runtime.

Example:

// Assegnazione di una funzione a una variabile
const saluto = function(nome) {
     return `Ciao, ${nome}!`;
};

console.log(saluto(“Marco“)); // Output: Ciao, Marco!

// Passare una funzione come argomento a un’altra funzione
function eseguiFunzione(f) {
     return f(“Sara“);
}

console.log(eseguiFunzione(saluto)); // Output: Ciao, Sara!

In this example, the function saluto is assigned to a variable as if it were any other value. Next, it is passed as an argument to another function, eseguiFunzione, which executes it.

Implications of the First-Class Concept.

Because of this concept, functions can be used to construct powerful abstractions. Abstractions allow you to hide implementation details and focus on more general logic.

1. Callback Functions.

Callback functions are a common example of the use of functions as first-class citizens. A callback function is a function passed as an argument to another function, which then “calls it back” (i.e., executes it) when needed.

Example:

function operazione(matematica, a, b) {
        return matematica(a, b);
}

function somma(x, y) {
        return x + y;
}

console.log(operazione(somma, 3, 4)); // Output: 7

In this example, somma is a callback function passed to operazione, which executes it with parameters a and b. This is a simple example, but the concept can be used to implement more complex logic such as handling events or using asynchronous functions.

2. Anonymous Functions and Arrow Functions

Another feature of JavaScript is the ability to define anonymous functions, that is, functions without a name. These are very useful when you want to pass a function as an argument without explicitly declaring it.

Example:

setTimeout(function() {
console.log(“Eseguiamo questa funzione dopo 2 secondi“);
}, 2000);

Here, an anonymous function is passed as a callback to setTimeout, which will execute it after a certain period of time.

Arrow functions are a more compact and modern version of anonymous functions:

setTimeout(() => {
console.log(“Eseguiamo questa funzione dopo 2 secondi“);
}, 2000);

Functions as Abstractions

Functions in JavaScript are abstraction tools, since they allow us to define generic behavior that can be reused in different contexts. Abstraction is the process of hiding complexity and focusing on fundamental concepts, allowing for more modular, readable, and maintainable programming.

1. Higher-Order Functions.

Higher-order functions are functions that accept other functions as arguments or return a function as a result. This approach is powerful because it allows more abstract and flexible solutions to be created.

Example:

function creaMoltiplicatore(fattore) {
       return function(numero) {
          return numero * fattore;
       };
}

const moltiplicaPerDue = creaMoltiplicatore(2);
console.log(moltiplicaPerDue(5)); // Output: 10

In this example, creaMoltiplicatore is a higher-order function that returns a new function. The resulting function is used to multiply a number by the factor given as an argument to the main function.

2. Closures.

Functions in JavaScript, because of their closure behavior, can remember the environment in which they were created, allowing them to access variables that are no longer in the current scope.

Example:

function creaContatore() {
     let contatore = 0;
     return function() {
         contatore++;
         return contatore;
     };
}

const incrementa = creaContatore();
console.log(incrementa()); // Output: 1
console.log(incrementa()); // Output: 2

In this example, the function returned by the creaContatore function “closes” on the context of the contatore variable, allowing it to hold its value even after creaContatore has finished executing.

Advantages of Abstractions with Functions.

-Modularity: Abstract functions allow complex problems to be decomposed into smaller, more manageable components.

-Reusability: An abstract function can be reused in different contexts with different parameters.

-Maintenance: Separation of concerns by functions makes the code easier to understand and maintain.

Conclusion

Functions as first-class citizens in JavaScript allow considerable flexibility in writing code, allowing them to be used like any other value. This, along with their ability to act as abstractions, allows code to be written that is more modular, reusable and maintainable. The use of functions as callbacks, higher-order functions and closures is an essential part of a functional programming approach, which is widely supported in JavaScript. In JavaScript, functions can be classified as pure or impure based on their behavior and the effect they have on external state. Here is an explanation of both:

Pure Functions:

A pure function is a function that:

1. Depends only on its arguments: the result of the function depends solely on the parameters it receives, without relying on external variables or global states.

2. Has no side effects: does not change the state external to the function (e.g., does not change global variables, does not do I/O, does not change the input received).

3. Deterministic: given the same input, it will always return the same output.

Example of a pure function:

function somma(a, b) {
      return a + b;
}

In this case, the somma function is pure because:

-Depends only on parameters a and b.

-Does not modify external variables.

-It will always return the same result for the same input values.

Impure Functions:

An impure function is a function that:

1. Relies on external states or global variables: the result may depend on variables external to the function or on modifiable states during program execution.

2. Has side effects: may modify external variables, do I/O operations (such as interacting with the DOM or sending HTTP requests), or change global state.

3. Non-deterministic: it can return different results even with the same inputs if the external state changes.

Example of an impure function:

let x = 10;

function sommaImpura(a) {
    return a + x;
}

In this case, the function sommaImpura is impure because:

-The result depends on the external variable x.

-If x changes, the function will return a different result even if a remains the same.

Why are pure functions useful?

Pure functions are easy to test, predictable and easier to parallelize because they do not depend on external states and have no side effects. Pure functions may be necessary in some situations, such as interacting with the user or updating the DOM, but they must be used carefully.

THE JAVASCRIPT LANGUAGE

THE JAVASCRIPT LANGUAGE

LINK TO THE CODE ON GITHUB

GITHUB