Funciones en Node.js y JavaScript. Lo realmente importante

Functions in Node.js and JavaScript. What's really important

Like Objects in Node.js and Javascript. What's really important. “Functions in Node.js and JavaScript. What's really important” refers to the principles behind functions, which is really important to continue learning, improve your understanding of functions in programming, Node.js and in Javascript.

Before talking about functions in Node.js and JavaScript, it is worth remembering or defining what a function is in programming.

What are functions?

Functions are a very important element in any programming language. We know that the functional programming was even invented before any programming language based on the lambda calculation of Alonzo Church.

Sintaxis calculo lambda, programación funcional
Lambda calculation syntax, functional programming. Image taken from https://www.slideshare.net/FASTPresentations/introduction-to-lambda-calculus-using-smalltalk-by-facundo-javier-gelatti

In the first programming languages, subroutines, procedures and functions were used. Subroutines, procedures and functions have in common that they group a set of operations with the purpose of reusing them many times and only writing them once.

Functions, unlike procedures and subroutines, are still used in modern programming languages, and are the smallest unit of code organization. They are used to define the behavior of objects, composing them with specific functionalities. Let's remember another post that the Objects are a group of functionalities that contribute to communication with other objects.

Without functions, an object wouldn't be of much use. Functions define the behavior of objects. And it also forms larger functions. In conclusion, the functions serve us for.

  • Organize the code
  • Reuse code
  • It is used for the composition of objects, adding behaviors.
  • It is used for the composition of more complicated functions

What are functions in Node.js and JavaScript?

In Node.js and JavaScript, and indeed in any environment where JavaScript is executed, functions are everything described in the previous section. And also They are objects.

  • Since they are objects, they can be treated like any other value:
    • They can be assigned to variables and properties of other objects
    • Create them dynamically during the execution of the JavaScript code
    • Have its properties and methods
    • Be parameters for another function
    • Be the return value of a function
  • Additionally, the body of a function provides local scope to variables and parameters.

Although it is not the topic of this post, all the features listed make JavaScript can be used as a functional programming language.

How to create functions in Node.js and JavaScript?

The three recommended ways to create functions are as follows.

  • Normal declaration
  • Function as expression
  • Arrow functions

Function declaration

This is the most common method, very similar in other programming languages. The reserved word is used functions, followed by the function name, then a list of arguments in parentheses, which are separated by commas. This argument list is optional.

Finally the function body using braces { }. The body of the function contains the statements you need.

functions name(argumento1, argumento2, ...argumentoN) {
  // sentencias
}

Concrete example:

functions sumar(to, b) {
  return to + b;
}
sumar(1, 2); // 3

To execute the function code it is necessary to invoke it. The invocation is made with a pair of parentheses and the necessary arguments inside, separated by commas. Just like the previous example.

A function always returns some value, even if it is not explicitly defined. If you do not define what a function returns, by default the return value will be undefined.

functions sumarSinReturn(to, b) {
  const resultado = to + b;
}
sumarSinReturn(1, 2); // undefined

If we execute the function, it returns undefined because we don't explicitly tell it to return some value

Function in expression form

This way of creating functions is much more flexible, its definition can appear wherever an expression can be defined. That gives it the ability to be assigned to a variable or a property of an object.

Its syntax is the same as the declaration of a function that we saw previously, but when assigned to a variable or property, its name is optional.

functions [nombreOpcional](argumento1, argumento2, ...argumentoN) {
  // sentencias
}

Next we will see some examples.

// Sin nombre, tambie  conocida como funcion anonima
const sumar = functions(to, b) {
 return to + b;
};
// Con nombre
const sumar = functions sumar(to, b) {
  return to + b;
};
const calculadora = {
  sumar: functions(to, b) {
    return to + b;
  }
};
const person = {
  // como propiedad de un objeto
  eat: functions() {
    return 'Comiendo...';
  }
};

Arrow functions

Arrow functions are the newest way to create functions, much more similar to mathematical functions in algebra. They feel very convenient because their syntax is much more reduced. They are an alternative to functions in the form of expressions, they are faster to write. However, it has many limitations compared to the other two ways of creating functions. Although if you use them for functional programming they are quite effective.

To be honest, it seems to me that if its use is not focused on functional programming, it does add more complexity to the use of functions in JavaScript, in itself the functions in Node.js and Javascript can be very different compared to other languages.

But well, let's look at its syntax.

argumento => expresión;
// Com mas de un arguento es necesario parentesis
(argumento1, argumentN) => expresión;
// Con varias lineas de sentencias, es necesario las llaves {}
argumento => {
 // sentencias
};
// Con mas de un argumento y con varias lineas se sentencias
(argumento1, argumentoN) => {
  // sentencias
};
// Sin argumentos es necesario los parentesis
() => expresión

When using expressions, it is not necessary to explicitly define the return. The result of the expression is the return value.

const calcularCuadrado = to => to * to;
const sumar = (to, b) => to + b;
const greet = () => 'Hola';
// invocaciones
calcularCuadrado(5); // 25
sumar(1, 2); // 3
greet(); // 'Hola'

When we want the body of the function to have several lines of statements, curly braces are used. Furthermore, if we want the function to return some value, then we explicitly use the syntax of return.

Examples.

const calcularCuadrado = to => {
  const result = to * to;
  return result;
};
const sumar = (a, b) = > {
  const result = to + b;
  return result;
};
// invocaciones
calcularCuadrado(5); // 25
sumar(1, 2); // 3

Nested or internal functions

A function can be defined inside another function, that is, we can dynamically create internal functions inside another main function and invoke them.

functions greet() {
  functions saludarInterna() {
    return 'Hola';
  }
  const saludo = saludarInterna();
  console.log(saludo);
}
greet(); // 'Hola'

In the next section we will see other nested functions.

Local scope of functions

Functions in Node.js and JavaScript provide a scope of values, local to the body of the function, that is, what is defined in the body of the function can only be referenced within the function.

functions grandfather() {
  const name = 'Jaime';
  const last name = 'Cervantes'
  functions father() {
    const last name = 'Good day';
    functions son() {
      const last name = 'Pérez';
      const nombreCompleto = `${name} ${last name}`;
      console.log(nombreCompleto); // Jaime Pérez
    }
    son();
    const nombreCompleto = `${name} ${last name}`;
    console.log(nombreCompleto); // Jaime Buendía
  }
  father();
  const nombreCompleto = `${name} ${last name}`;
  console.log(nombreCompleto); // Jaime Cervantes
}
grandfather();

Internal functions can access the variables of their parent function (so to speak). In the previous example you can see that the function sonor you can refer to the constant name of the function grandpaeither. This produces us Jaime Perez. In the next section we explain it better

Closures or closures

Function nesting allows child functions to have their own local scope, hidden from parent functions. At the same time these internal functions have access to the values defined in the parent functions. This encapsulation of information and at the same time access to external information is called closure.

Let's continue with the example from the previous section, the functions grandfather, father and son

functions grandfather() {
  const name = 'Jaime';
  const last name = 'Cervantes'
  functions father() {
    const last name = 'Good day';
    functions son() {
      const last name = 'Pérez';
      const nombreCompleto = `${name} ${last name}`;
      console.log(nombreCompleto); // Jaime Pérez
    }
    son();
    const nombreCompleto = `${name} ${last name}`;
    console.log(nombreCompleto); // Jaime Buendía
  }
  father();
  const nombreCompleto = `${name} ${last name}`;
  console.log(nombreCompleto); // Jaime Cervantes
}
grandfather();

The result of the function invocation grandfather is:

Jaime Pérez --> From son function Jaime Buendía --> From father function Jaime Cervantes --> From grandfather function

The more internal the function, the more scope it has to all the areas of the other “external parent” functions. Like the image below, it is as if the function scopes grandfather and father were within the scope of the function son.

Closure, ámbito de funciones en js
Closure, function scope in js

A function will always take the value of the variable that is closest to its own local scope. The variables within their own local scope are the most relevant. This allows variable and constant names to not collide between nested scopes.

The function son, has access to the constants name and last name of the function grandfather. You also have access to the constant last name of the function father. But the constant last name within the function itself son is closer than defined in father and grandfather, has greater relevance. So the full name that is printed to the console is Jaime Perez instead of Jaime Buendía or Jaime Cervantes.

The function father if you have access to the constants name and last name of the function grandfather. In its own sphere it has a constant last name equal to Good day. As this value is closer, it does not take the last name of the function grandfather which is further away. That is why in the console the full name that is printed is Jaime Buendía. Then the function father You do NOT have access to the constant last name of the function son.

Finally it prints to the console Jaime Cervantes Velasco because the constants name and last name They are defined at the local level of the grandfather function. The grandfather function does NOT have access to constants last name of its internal functions father and son.

OOP emerged from functions

Now that we've seen a little about nested functions and closures, we can talk about how object-oriented programming was discovered. This reflects the importance of functions in programming languages.

Ole Johan Dahl and Kristen Nygaard realized that the function call stack in ALGOL could be moved to a Heap. This allows variables declared by a function to exist even after the function finishes executing and returns some value.

In this way the function became the constructor of the class, the local variables became properties of the class instance, and the internal functions became its methods. And so in 1966 object-oriented programming was discovered.

We can implement this behavior using functions in Node.js and JavaScript and taking advantage of their ability to create closures.

functions createPerson(name, last name) {
  functions greet() {
    return `Hola soy ${name}...`;
  }
  functions eat() {
    return 'Comiendo...';
  }
  functions getName() {
    return `${name} ${last name}`;
  }
  const instancia = {};
  instancia.greet = greet;
  instancia.eat = eat;
  instancia.getName = getName;
  return instancia
}
const James = createPerson('Jaime', 'Cervantes');
James.eat(); // Comiendo...
James.greet(); // Hola soy Jaime
James.getName(); // Jaime Cervantes

The parameters name and last name, are within the local scope of the function createPerson, so they work just like variables inside the function body. The inner functions continue to have access to those parameters even after the parent function returns its value, an object literal that is the instance of a person.

Then when the instance James invokes its method getName, this property refers to the internal function getName of the function createPerson. Due to internal function closure getName, we have access to the parameters name and last name even long after the parent function createPerson has returned its value.

Function Names in Node.js and Javascript

We have to be aware that programming and software development is a social activity, with a lot of communication. And the more efficient this communication is, the greater the success of the software. This allows us to save the time and financial resources of everyone involved. I'm talking about programmers and non-programmers, investors, clients and users.

One of the forms of communication between fellow programmers and often oneself in the future is through easy-to-understand code, and to contribute to this easy understanding we must choose the name of our functions very carefully.

Take into account the following recommendations. But keeping in mind that these are only examples, and when it comes to writing your real functions and with the proper context, you will most likely be able to come up with better function names than those shown here.

Spend enough time naming your role.

Just as important as naming the variables is the functions. Functions are the smallest units that allow us to define behaviors in applications. The time spent naming your functions is much less than the time you have to spend later on yourself and your colleagues trying to figure out what a function actually does. It's like organizing your room, the tidier it is, the faster you will find the things you need, the faster you will change, or the faster you will find your socks, etc.

The name must be very semantic, describe its objective

The name of a function should describe as clearly as possible what it does. It is important that be a verb because a function always performs one or more operations focused on a specific task.

For example, if a function returns the full name of a person, which of the following names fits best?

fullName()
getName();
getFullName()

The name that best describes the purpose of the function is getFullName.

If the function returns a boolean, the function name must indicate that the result can be true or false. Just like the result of a logical condition. It's like asking a question whose possible answers can only be yes or no.

hasChildren(person) {
  return Boolean(person.childre.length);
}
if (hasChildren(currentPerson)) {
  // Haz algo
}

Yeah hasChildren If it were a method, it would look like this.

if (currentPerson.hasChildren()) {
  // Haz algo
}

You notice how the condition reads like a very understandable phrase. If currentPerson has children, then...do something.

Avoid wrong assumptions

If the name describes things it doesn't actually do, then we should rename that function. For example, if a function forms the full name of a customer and returns that name. Which feature best prevents erroneous assumptions?

functions setClientName() {} // Se entiende que el nombre del cliente va a ser modificado
functions getFullClientName() {} // Aquí esta claro que solo consigue el nomnbre completo del cliente

setCustomerName It tells us that the client's name will be changed, it is a bad name. So the name that best avoids erroneous assumptions is getFullClientName. It does not say what forms the name, but it does say that it will return a full name. For practical purposes we are not interested in knowing how that full name is formed, just that it does not return them.

Agreements with programmers

It is very important to establish agreements for the appointment of functions. In the previous examples I have been using the prefix get which indicates that I send to obtain something. But it would be confusing if some programmers used the word fetch and others the word retrieve, and others collect either bring.

Use the right context

It is important to understand the context of the function, in previous examples we used the function getFullClientName, but depending on the context of the application, it might be better getFullUserName either getFullEmployeeName.

Although these names have to do with the context of the business or problem, there are also technical terms that programmers are already very accustomed to and should not be mixed with the problem domain.

For example, the observer design pattern contains methods like update, subscribe, publish, notify. If we are working with a magazine application that uses native cell phone notifications, SMS, and makes periodic publications. This can also create confusion, so you should name functions very carefully in such a way that you distinguish between functions or methods of the design pattern and others related to the business.

Function scope helps name length

The name of the functions can be long or short depending on the scope it has in the software. For example, a function that is used a lot in different files is worth keeping its name short. Because if many people use it, it is important that it is easy to write and pronounce.

On the other hand, if it is a function that is only used in a file, its name can be long, these types of functions are normally used internally by other functions with short names. So long name functions are a way to explain what the short name function does. This doesn't mean it can't be short, but if you need more words to better describe the feature, go ahead.

As an example, let's imagine a function that returns the total of your profits to the current date of your entire investment portfolio. Where the profits are the sum of the interest on your investments plus the contributions you have made to date.

// funcion corta, reutilizable en otros archivos o aplicaciones
functions getEarnings() {
  return calculateEarnings();
}
// funciones con nombre más largo que describen a la funcion corta
functions calculateEarnings() {
 const earnings = calculateCurrentTotalInterest();
 const aditionals = calculateCurrentTotalAdditionalContributions();
  return earnings + aditionals;
}
functions calculateCurrentTotalInterest() {}
functions calculateCurrentAdditionalContributions() {}

Don't worry so much about these examples, the goal is to give you an idea. In a future publication we will make a small application where we will see how to apply these recommendations.

Conclusions

Functions in Node.js and Javascript is a fairly broad topic, it is one of the best done things in JavaScript that reveal the power of the language. It is noted that Javascript is influenced by LISP and Scheme.

Likewise, let's not forget to name our functions correctly, they are the smallest units that allow the software to be organized into well-defined behaviors.

Functional programming is the first programming paradigm invented, hence the importance of functions, because it is a paradigm from which object-oriented programming took its bases.

Let's not forget that functions in Node.js and JavaScript are objects and therefore can be treated like any value.

We are still missing several important feature topics. These are addressed in this post. If you have any questions, do not hesitate to write them in the comments, we will be happy to help you!

If you want, as an exercise, you can translate all the examples into functions in the form of expression and arrow functions. Have fun!

Objetos en Node.js y Javascript. Lo realmente importante

Objects in Node.js and Javascript. What's really important

Introduction

Objects in Node.js and Javascript. What's really important” refers to the principles behind objects, which is really important to continue learning, improving the understanding of objects in programming and in Node.js and Javascript.

Let's start with understanding what an object is in programming.

What are objects in programming?

It has been said a lot that object-oriented programming represents the real world. The truth is that programming in general is about representing the real world in something digital. So object-oriented programming is also about digitally representing the real world, just with a little more emphasis on the use of objects. But as we have established in this post, the important thing is NOT the objects, the important thing is:

Message passing for communication between objects

In programming a object It is a digital form of group features and that some of them may be analogous to an object in real life, but that it is much more limited and should not be expected to be the same, because it is only a digital representation.

When you develop software, and you need to add functionality, modify or fix a bug, your logical thinking is based on representation of digital objects, their relationships and communications with other digital entities. You should never think that as the real object behaves in a certain way, so does its representation. It is very helpful conceptually, but in implementation they are very often different.

Let's remember what Alan Kay tells us:

I'm sorry I coined the term a long time ago. Objects for programming because it made people focus on the least important part. The big idea is "Sending messages«

Alan Kay

Also a object serves for store data useful that other objects can use. So an object serves us to:

  • Create communications between digital representations of objects.
  • It allows grouping functionalities related to the digital representation of the object.
  • Stores data that another object can use. (It works like some data structures.)

What are objects in Node.js and JavaScript?

The objects in Node.js and Javascript, they are a collection of pairs name: value, similar to PHP's "associative arrays." These pairs of name/value They are called properties, a property is like a variable and can contain any type of value.

The key to the previous paragraph is that it can contain any type of value, including functions. And with this two types of objects are identified.

  1. Objects with functionalities and communications
    1. Which for the most part have methods to communicate with other objects and solve problems.
  2. Objects with data. Also called data structure
    1. Which for the most part contains data and which helps us to store and send information through messages. These objects are used by objects with functionalities and communications.

Let's remember that everything related to objects also works anywhere JavaScript is executed, node.js including.

How to create objects in Node.js and Javascript?

The simplest way to create an object is through an object literal. A literal object is one that is created with curly braces {}, adding its properties and methods. Like the following example.

const James = {
  name: 'Jaime',
  last name: 'Cervantes',
  mother's last name: 'Velasco',
  edad: 33,
  getName: functions () {
    return 'Jaime Cervantes Velasco';
  }
};
James.getName(); // Jaime Cervantes Velasco

We have an object with five properties, name, last name and mother's last name are of type string, age is type number and the last property, getName() is type functions. Here you have more information about data types.

Although we will see the functions in detail later, for now, we can say that the functions allow us to encapsulate and execute a set of operations that we do very often. Instead of repeating the code of these operations many times, we better put these operations inside a function.

Whenever we need to execute these operations, we simply execute the function, this execution of the function is called invocation. Example of invocation is in the last line, where we use parentheses, jaime.getName();.

How do I get the value of a property?

To obtain some property of an object, we can do it in two ways:

  • Dot notation
  • Using square brackets, much like accessing data in a array

The first way, dot notation, is very simple, example:

const James = {
  name: 'Jaime',
  last name: 'Cervantes',
  mother's last name: 'Velasco',
  edad: 33,
  getName: functions () {
    return 'Jaime Cervantes Velasco';
  }
};
James.name // 'Jaime'
James.last name; // 'Cervantes'
James.mother's last name; // 'Velasco'
James.edad; // 33
James.getName // function ()  { return 'Jaime Cervantes Velasco'; }

The second way, using square brackets [], example:

const James = {
  name: 'Jaime',
  last name: 'Cervantes',
  mother's last name: 'Velasco',
  edad: 33,
  getName: functions () {
    return 'Jaime Cervantes Velasco';
  }
};
jaime['name'] // 'Jaime'
jaime['last name']; // 'Cervantes'
jaime['mother's last name']; // 'Velasco'
jaime['edad']; // 33
jaime['getName'] // function ()  { return 'Jaime Cervantes Velasco'; }
jaime['getName']() // 'Jaime Cervantes Velasco'

Here we access the properties with square brackets using the name of the properties, which are strings.

Highlights how we invoke the function getName. These two statements do the same thing, invoke the function getName:

jaime.getName(); jaime['getName']();

Property names are character strings

When we use square bracket notation, we use a string of characters to get the value. What we mentioned before about An object is a collection of pairs name: value. He name of all properties are strings.

Since property names are strings, we can define properties enclosed by quotes, like the following example:

const James = {
  name: 'Jaime',
  last name: 'Cervantes',
  mother's last name: 'Velasco',
  edad: 33,
  getName: functions () {
    return 'Jaime Cervantes Velasco';
  },
  'nueva-propiedad-con-guion-medio': 'Mi propiedad con guión medio encerrada por comillas'
};
jaime['nueva-propiedad-con-guion-medio']; // 'Mi propiedad con guión medio encerrada por comillas'

And get them with bracket notation like this, jaime['new-property-with-middle-hyphen'].

A property like this cannot be accessed with dot notation, so jaime.new-property-with-script.medium. This statement will give you an error in Javascript because it is not a valid property name.

In fact in Javascript the name of valid variables or properties must:

  • Start with a letter, included $ and _.
  • It cannot begin with numbers or characters used in the language for other purposes, e.g. -, %, /, +, &.
  • After the starting letter you can use numbers, other valid letters, $ and _.

Objects in Node.js and Javascript that contain other objects?

An object can contain any type of data, so it can contain other objects. Let's look at an example:

const James = {
  name: 'Jaime',
  last name: 'Cervantes',
  mother's last name: 'Velasco',
  edad: 33,
  getName: functions () {
    return 'Jaime Cervantes Velasco';
  },
  address: {
    calle: 'Melchor Ocampo',
    numero: 2,
    colonia: 'Las Flores',
    municipio: 'Tezonapa',
    estado: 'Veracruz'
  }
};

Here we add an object address to the object James. Simply using curly braces to create object literals.

How do I add, modify and delete properties?

Once you create an object, you can add more properties, modify them, and delete them.

Add properties to objects in Node.js and Javascript

Assignment is used to add new properties that do not previously exist.

const James = {
  name: 'Jaime',
};
James.last name = 'Cervantes';
James.appelidoMaterno = 'Velasco';
console.log(jaime ); // { nombre: 'Jaime', apellidoPaterno: 'Cervantes', apellidoMaterno: 'Velasco }

Update properties to objects in Node.js and Javascript

Assignment is also used to update the value of properties that already exist.

const James = {
  name: 'Jaime',
  last name: 'Cervantes',
  mother's last name: 'Velasco',
};
James.last name = 'Perez'
James.mother's last name = 'Moreno';
console.log(jaime ); // { nombre: 'Jaime', apellidoPaterno: 'Perez', apellidoMaterno: 'Moreno' }

Remove properties from objects in Node.js and Javascript

To delete properties, use the operator delete. Example:

const James = {
  name: 'Jaime',
  last name: 'Cervantes',
  mother's last name: 'Velasco',
};
delete James.last name;
// o tambien así:
delete jaime['apellidoMaterno];
console.log(jaime); // { nombre: 'Jaime' }

The properties last name and mother's last name, no longer exists in the object James.

Are objects in Node.js and Javascript a reference or a value?

Objects in Node.js and JavaScript will always be a reference, that is:

const James = {
  name: 'Jaime',
  last name: 'Cervantes',
  mother's last name: 'Velasco',
};
const Pedro = James;
Pedro.name = 'Pedro';
James.name === Pedro.name; // true;
James.name; // 'Pedro'
Pedro.name; // 'Pedro'

The constants James and Pedro they refer to same object in memory.

How do I cycle through the properties of an object?

There are several ways, the simplest to go through the properties of an object is the following.

We have the object James:

const James = {
  name: 'Jaime',
  last name: 'Cervantes',
  mother's last name: 'Velasco',
  edad: 33,
  getName: functions () {
    return 'Jaime Cervantes Velasco';
  }
};

The first thing is to obtain the name of its properties with the method Object.keys, which generates a array with the names of the properties.

const namesProps = object.keys(jaime);
console.log(nombresProps); // ["nombre", "apellidoPaterno", "apellidoMaterno", "edad", "getNombre"]

Now we go through the arrangement namesProps to get the values.

namesProps.forEach(nombreProp => {
  console.log(James[nombreProp]); // imprime el valor del nombre de propiedad actual
});

The result of the above code is something like the following.

'Jaime'
'Cervantes'
'Velasco'
33
functions () {
  return 'Jaime Cervantes Velasco';
}

The prototype of an object?

Javascript is a multi-paradigm programming language, On its object-oriented side, it does not use classes for code reuse, rather it uses object composition. But how do you do this composition of objects?

Better object composition over class inheritance

Better object composition over class inheritance

Design Patterns: Elements of Reusable Object-Oriented Software

This principle is widely applied in Javascript and therefore applies in the same way in Node.js, in fact that is how it was built. Every object in Javascript has a link to a prototype, and can use all the properties and functions of its prototype.

This prototype link can be referenced in code, using the special property __proto__.

In the case of literal objects, such as James, are linked to Object.prototype, which is the base object of all objects in Javascript.

const James = {
  name: 'Jaime',
  last name: 'Cervantes',
  mother's last name: 'Velasco',
  edad: 33,
  getName: functions () {
    return 'Jaime Cervantes Velasco';
  }
};
James.__proto__; // { constructor: f Object(), hasOwnProperty: f hasOwnProperty, ... }
James.__proto__ === object.prototype; // true
James.toString === object.prototype.toString; // true
James.toString(); //[object Object]

If we expand the prototypes in a web browser like chrome, it is displayed like this.

Objeto literal tiene como prototipo a Object.prototype
Object literal jaime has Object.prototype as its prototype

Graphically, the prototype link looks like the image below.

Object.prototype el prototipo de jaime
Object.prototype jaime's prototype

You can also see the prototype at node.js if you link it to a debugger. But we won't see how to do that today.

What is the prototype chain?

We have created the object James literally, but what if we create it through another object person, making the person object its immediate prototype.

const person = {
  greet: functions () {
    return 'Hola';
  },
  eat: functions () {
  	return 'comiendo...';
  }
};
const James = object.create(persona); // Creamos jaime en base al prototipo persona

If we now do a console.log(jaime):

console.log(jaime);

And we expand the result in a web browser like Chrome, the result is displayed as follows.

Cadena de prototipo
prototype chain

In the image, we can see that [[prototype]] points to the object person, hence James has access to the methods eat and greet of the object person.

And if we make these comparisons we see that the link to the person prototype exists.

James.__proto__; // { saludar: f (), comer: f () }
James.__proto__  === person; // true

We can invoke the methods eat and greet of the person object as if they were James.

James.eat();  // 'Comiendo...'
James.greet(); // 'Hola'

Now if we expand the last [[prototype]] What do you think the result will be?

Cadena de prototipos Object.prototype
Object.prototype prototype chain

We clearly see that the last [[prototype]] is Object.prototype, the base prototype of all objects in Javascript. And you can check it in code by comparing Object.prototype with special properties __proto__.

James.__proto__.__proto__ === object.prototype; // true

We can also use the method toString as if it were from James.

James.toString(); // [object Object]

This is called a prototype chain., an object can have the necessary sub prototypes to reuse its properties and methods. In this case it was like this, jaime → person → Object.prototype.

jaime --> persona --> Object.prototype
jaime –> person –> Object.prototype

Peculiarities with the prototype chain

Use the methods and properties of sub prototypes

The object James you can directly use the properties and methods of your prototypes.

James.toString(); // '[object Object]' --> de Object.prototype
James.hasOwnProperty('name'); // true --> de Object.prototype
James.greet(); // 'Hola' --> de persona
James.eat(); // 'Comiendo...' --> de persona
James.name; // 'Jaime' --> de si mismo, objeto jaime

Updating properties does not affect the prototype chain

When we have a property that exists in multiple sub prototypes, javascript uses the one that is closest in the prototype chain. Suppose we want to change the behavior of the method toString in James so instead of using Object.prototype.toString, to James We add a method with the same name.

You can say that what we are doing is updating it.

James.toString = functions () {
  return `${this.name} ${this.edad}`;
};
James.toString(); // 'Jaime 33'

Now the method is used toString of James, the prototype chain is not traversed until reaching Object.prototype.toString as was done in the previous examples. Because there is already a method toString directly in our object James.

The operator delete does not remove properties from prototypes

When we occupy the operator delete, this never touches the prototype chain, it only eliminates the properties of the object in question.

If a property with the same name as the one we removed exists in the prototype chain, then now that property in the prototype chain will be used.

Using the previous example, of the method toString of James, if we eliminate it with delete, so now the toString() of Object.prototype It is the one that will be used because the person object does not have that method directly.

James.toString = functions () {
  return `${this.name} ${this.edad}`;
};
James.toString(); // 'Jaime 33'
delete James.toString
James.toString(); // '[[object Object]]' --> De Object.prototype

In the last line we notice that now James use the again toString() of Object.prototype.

Examples of predefined objects in Node.js and Javascript

As we have already mentioned in other publications, except for primitive types, everything else in javascript are objects. In future publications we will see more detail about type objects functions and array

How to create an object functions?

functions printPerson(person) {
  console.log(person.name);
  console.log(person.edad);
}

As the function printPerson It is an object, we can add properties to it without any problem.

printPerson.miPropiedad = 'Mi propiedad de una funcion';
console.log(imprimierPersona.miPropiedad); // 'Mi propiedad de una funcion

The functions are very useful, so versatile that with them we can generate new objects, but that topic does not belong to this publication.

How to create an object array?

The recommended way is to simply create them using square brackets [].

const vacio = [];
const numeros = [1, 2, 3, 4, 5, 6];
const animales = ['perro', 'gato', 'caballo'];
const conObjetos = [
  		{
          name: 'Jaime',
          edad: 33
        },
        functions printPerson(person) {
          console.log(person);
        }
	];

Since an array is an object, just like a function, you can also add properties to it.

const numeros = [1, 2, 3, 4, 5, 6];
numeros.miPropiedad = 'Mi propiedad de un arreglo';
console.log(numeros.miPropiedad); // 'Mi propiedad de un arreglo

He array is the clearest object to use as a data structure.

How to create an object date?

const fecha = new date();
console.log(fecha); // Fri May 28 2021 10:46:27 GMT-0500 (hora de verano central)

As you can imagine, we can also add properties to the date object because it is an object

Conclusion

In Javascript and on any platform where it is executed, an example is in node.js, they have the peculiarity of always having a link to a prototype. This is how the language is designed. I already know that classes currently exist, but in reality these are functions that internally make use of prototypes, we will also explain this in another publication.

With the exception of primitive data, everything else in Javascript is objects, it is important to know how they work so as not to get stuck in this learning.

With this information you have enough to continue advancing and use items more wisely.

The topic of objects is quite extensive, there are still many things to take into account, but there is already too much information that we have to divide it into more publications. So very soon we will continue. If you have any questions, do not hesitate to write them in the comments, we will be happy to help you!

¿Cómo funciona React con ReactDOM y JSX?

¿Cómo funciona React con ReactDOM y JSX?

En esta publicación veremos como crear un componente, y comprender como se relaciona react con ReactDOM and JSX. Tener buenos fundamentos sobre el funcionamiento de React es muy importante para aprender más rápido esta librería. Además, al entender bien estos fundamentos, es fácil arreglar errores a la hora de crear nuestros componentes y aplicaciones.

Primero utilizaremos solo react para crear un elemento y ReactDOM para pintarlo, luego agregaremos JSX y finalmente veremos como podemos convertir ese elemento en un componente reutilizable.

Para los que no tienen idea que es React, es una librería escrita en JavaScript que facilita la creación de interfaces gráficas de usuario para aplicaciones web y móviles. Esta basada en componentes y composición en lugar de herencia.

Vamos a usar una herramienta en línea llamada condesandbox. Aquí crearemos un nuevo sandbox con la plantilla de HTML 5, tambien se le llama static.

Plantilla sandbox HTML5
Plantilla sandbox HTML5

Luego creamos un archivo api-dom.html y otro react.html, en el body de ambos archivos agregamos un div con el atributo id igual a "raiz-app", en este elemento contenedor vamos a insertar todos los elementos nuevos.

Todo lo referente a API DOM deber estar en el archivo api-dom.html y todo lo referente a react in react.html.

API DOM: Crear un elemento saludo simple

El objetivo es crear un elemento donde saludemos a nuestro usuario a través de un texto. Primero usaremos el API del DOM que se encuentra en todos los navegadores. Esto nos ayudará a comparar y visualizar los beneficios de usar React.

<body>
  <div id="raiz-app"></div>
  <script>
    const saludo = document.createElement('div');
    saludo.textContent = 'Hola, soy un elemento saludo creado con API DOM';
    const raiz = document.getElementById('raiz-app');
    raiz.appendChild(saludo);
  </script>
</body>

Creamos un elemento div y dentro agregamos el texto del saludo. Finalmente agregamos nuestro saludo a nuestro contenedor raiz-app con node.appenChild(node).

Si abres tu archivo api-dom.html usando el navegador web del lado derecho de la interfaz de condesandbox, el resultado debe ser algo así.

Resultado de document.createElement
Resultado de document.createElement

React: crear elemento saludo

Ahora vamos a crear el mismo elemento de la sección anterior con React.

Importar código de la librería

Para empezar a utilizar React es necesario descargar su código, existen varias formas de usar el código de React, por el momento simplemente descargamos la librería usando la etiqueta <script> dentro de la etiqueta <head> de nuestro archivo react.html. De la siguiente manera.

<head>
  <title>React.createElement</title>
  <script src="https://unpkg.com/react@17/umd/react.development.js"></script>
</head>

Algo muy bueno de React es que separa las responsabilidades, lo que acabamos de agregar, descarga el código necesario para crear elementos y componentes. Para poder pintar esos elementos en nuestra página web, usamos ReactDOM. Pintar elementos en la página web desde luego que debe ser otra responsabilidad.

Para usar ReactDOM.render() necesitamos descargar su código usando de nuevo la etiqueta <script>, igual que hicimos con react.

<head>
  <title>React.createElement</title>
  <script src="https://unpkg.com/react@17/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
</head>

Crear saludo con React.createElement() y ReactDOM.render()

Ahora sí, creamos nuestro nuevo elemento usando React.createElement(component, props, ...children)

<body>
  <div id="raiz-app"></div>
  <script>
    const saludo = React.createElement(
      'div',
      null,
      'Hola, soy un elemento saludo creado con React');
	ReactDOM.render(saludo, document.getElementById('raiz-app'));
  </script>
</body>

La primera diferencia con document.createElement(), es que React.createElement() recibe como parámetros adicionales un objeto de propiedades y luego cualquier número de parámetros que se convertirán en elementos hijos.

De momento no le agregamos propiedades, pero si queremos agregar el saludo como un elemento de tipo texto, este elemento de tipo texto será un elemento hijo. Es lo que en API DOM seria node.textContent.

Finalmente pintamos nuestro saludo usando el método ReactDOM.render(). Por el momento digamos que ReactDOM.render() es como el node.appendChild().

Resultado de React.createElement
Resultado de React.createElement

Podemos agregar más elementos hijos simplemente agregando más parámetros, de la siguiente forma:

const saludo = react.createElement(
  'div',
  null,
  'Hola, soy un saludo creado con React',
  ' Y yo soy otro hijo',
  ' Y yo otro hijo más'
);
ReactDOM.render(saludo, document.getElementById('raiz-app'));

El parámetro children es un parámetro rest, el cual puede tomar cualquier número de parámetros e internamente hacer referencia a ellos a través de un array, React sabe como usarlos para pintarlos. En este ejemplo children contiene lo siguiente.

children = [
  'Hola, soy un saludo creado con React',
  ' Y yo soy otro hijo',
  ' Y yo otro hijo más'
];

API DOM: Modificamos el elemento saludo agregando propiedades y estilos

Nuestro elemento hasta ahora es demasiado simple, vamos a agregarle algunos estilos, y para eso vamos a utilizar dos propiedades, className and style.

const saludo = document.createElement('div');
saludo.textContent = 'Hola, soy un elemento saludo creado con API DOM';
saludo.className = "saludo";
saludo.style = 'font-weight:bold; text-transform:uppercase;';
const contenedor = document.getElementById('raiz-app');
contenedor.appendChild(saludo);

The property className no se llama class para evitar conflictos, debido a que class es una palabra reservada en JavaScript usada para definir clases.

Ahora creamos la reglas de estilo para la clase de estilos saludo. Vamos a usar la etiqueta <style> dentro de <head>.

<head>
  <style>
    .saludo {
      background: orange;
      padding: 16px;
    }
  </style>
<head>

The property style también aplica estilos, en este ejemplo pone el texto en negritas lo convierte a mayúsculas. El resultado debe ser algo como la imagen de abajo.

Resultado de document.createElement con estilos y propiedades
Resultado de document.createElement con estilos y propiedades

React: Modificamos el elemento saludo agregando propiedades y estilos

En props podemos agregar las propiedades que necesitemos, en este ejemplo solo agregamos className and style.

const saludo = react.createElement('div', {
    className: 'saludo',
    style: {
      'font-weight': 'bold',
      'text-transform': 'uppercase'
    },
  },
  'Hola, soy un elemento saludo creado con React'
);
const contenedor = document.getElementById('raiz-app'))
ReactDOM.render(saludo, container);

En la propiedad style, los estilos son agregados a través de un objeto en lugar de una cadena de caracteres, esto es más cómodo y legible, ¿Imagínate que fueran muchos estilos?, la supercadena larga que se formaría.

Tampoco no es que se recomiende esta forma de aplicar estilos a tus elementos en React, pero podemos aprovechar esta comodidad por el momento.

Otro beneficio en la propiedad style, es que en las declaraciones de estilos pueden ser escritas en camelCase, de hecho esa es la convención en Javascript y en React. Es más simple escribir en camelCase que estar encerrando todas las propiedades en comillas y con guiones medios entre palabras.

const saludo = react.createElement('div', {
    style: {
      fontWeight: 'bold',
      textTransform: 'uppercase'
    },
  },
  'Hola, soy un elemento saludo creado con React'
});

Si usas la forma, property-name, React te mostrara unos “warnings” en la consola. Estos “warnings” solo saldrán en modo develop, en producción no hay problema. Solo es una convención y no es obligatoria.

Warning: Unsupported style property font-weight. Did you mean fontWeight?
    at div
printWarning @ react-dom.development.js:61

Por último agregamos los estilos CSS que usara la clase saludo.

<head>
  <style>
    .saludo {
      border: 1px solid #eee;
      padding: 10px;
    }
  </style>
<head>

Al final debes tener un resultado como el de la imagen de abajo.

Resultado de React.createElement y definiendo propiedades
Resultado de React.createElement y definiendo propiedades

React: children in props

El contenido de nuestro saludo lo podemos agregar en el object props, en la propiedad children, en lugar del último parámetro de la función. children, en este caso funciona como la propiedad textContent del ejemplo usando API DOM.

const saludo = react.createElement('div', {
  className: 'saludo',
  style: {
    fontWeight: 'bold',
    textTransform': 'uppercase'
  },
  children: 'Hola, soy un elemento saludo creado con React'
});
ReactDOM.render(saludo, document.getElementById('raiz-app'));

En un ejemplo anterior comentamos que el tercer parámetro children es un parámetro rest, el cual recibe cualquier número de parámetros los almacena en un array. Pues la propiedad children también puede recibir un Array de hijos que React puede pintar.

const saludo = react.createElement('div', {
  className: 'saludo',
  style: {
     fontWeight: 'bold',
     textTransform: 'uppercase'
  },
  chidren: [
    'Hola, soy un saludo creado con React',
    ' Y yo soy otro hijo',
    ' Y yo otro hijo más'
  ]
);
const contenedor = document.getElementById('raiz-app');
ReactDOM.render(saludo, contenedor);

A lo mejor te parezca un poco complicado, pero es mucho más sencillo que el ejemplo del API DOM, imagínate que en lugar de texto fueran otros elementos como <h1>, <p>, otros <div>. Tendrías que crear elementos, agregarles el contenido y luego insertarlos dentro del elemento saludo.

Aun con este ejemplo, aunque es más sencillo que usar el API del DOM, se empieza a complicar cuando un elemento tiene muchos elemento hijos, por eso en React se recomienda usar JSX. Lo veremos a continuación.

React con ReactDOM y JSX

Ok, ya vimos como crear un elemento en React, pero ahora vamos a simplificar su implementación, JSX internamente utiliza React.createElement(component, props, ...children), pero estar llamando una función para crear un elemento complica la legibilidad del código.

Que tal si en lugar de escribir la función para crear un elemento, simplemente lo creas como cualquier otro codigo HTML, es mucho mas facil de escribir y leer, veamos la creación del elemento saludo con React y JSX.

const saludo = <div>Hola, soy un elemento saludo creado con React y JSX</div>;
const contenedor = document.getElementById('raiz-app');
ReactDOM.render(saludo, contenedor);

Mucha más fácil, ¿Cierto?, si te das cuenta no encerramos entre comillas el contenido del elemento saludo, JSX es lo suficientemente inteligente para entenderlo, pero para ellos es necesario descargar la herramienta llamada babel.js que lo hace posible.

Babel es una herramienta que no solo se encarga de convertir codigo JSX a invocaciones de React.createElement, sino que también convierte código con las últimas características del estándar ECMAScript a código que los navegadores web puedan entender. Para más información visita su sitio oficial.

Es importante aclarar que JSX internamente sigue siendo código JS, aunque parezca HTML y el uso de sintaxis HTML sea casi idéntica.

Usar babel para convertir JSX a JS

Todo muy bonito, pero para que podamos usar código JSX tenemos que descargar la herramienta.

<head>
 <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>

Al principio nuestro código lo insertamos dentro de las etiquetas <script>, pero para que babel pueda identificar que debe convertir codigo JSX a JS, es necesario decirle que es de tipo text/babel con el atributo type.

<script type="text/babel">
  const saludo = <div>Hola, soy un elemento saludo creado con React y JSX</div>;
  const contenedor = document.getElementById('raiz-app');
  ReactDOM.render(saludo, contenedor)
</script>

Ahora vamos agregar las propieades className y style para que tenga los mismos estilos que los ejemplos anteriores.

<script type="text/babel">
  const saludo = (
    <div
	  className="saludo"
	  style={{fontWeight: 'bold', textTransform: 'uppercase'}}
	>
      Hola, soy un elemento saludo creado con React y JSX
    </div>
  );
  const contenedor = document.getElementById('raiz-app');
  ReactDOM.render(saludo, contenedor)
</script>

Cuando se tiene más de una línea de JSX, es recomendado encerrarlo entre paréntesis para mejorar el entendimiento y evitar errores de JavaScript debido a la inserción automática de punto y coma.

Expresiones JS en atributos JSX

Algo interesante es como definimos el valor del atributo styles, usamos un par de llaves {}, todo lo que está encerrado en un par de llaves se ejecuta, por qué JSX lo identifica como una expresión de Javascript. En este caso JSX identifica que estamos definiendo un objeto para ser asignado a la propiedad style.

const saludo = (
  <div
  className="saludo"
  style={{fontWeight: 'bold', textTransform: 'uppercase'}}
  >
    Hola, soy un elemento saludo creado con React y JSX
  </div>
);

También podemos definir el objeto en otra línea y luego usar esa variable para realizar la asignación.

const styles = {fontWeight: 'bold', textTransform: 'uppercase'};
const saludo = (
  <div
  className="saludo"
  style={styles}
  >
    Hola, soy un elemento saludo creado con React y JSX
  </div>
);

El resultado de utilizar React con ReactDOM y JSX debe ser el mismo que en las últimas secciones, algo como la imagen de abajo.

Resultado React con JSX
Resultado React con ReactDOM y JSX

Componente reutilizable de React con ReactDOM y JSX

Ya que comprendemos la relación que tiene React con ReactDOM y JSX, es hora de que nuestro elemento saludo se convierta en un elemento reutilizable para saludar.

En Javascript el concepto de reutilización son las funciones, en React serian los componentes. Algo muy bueno de React, es que podemos hacer un componente usando una función. ¿Qué cosa puede ser más transparente que eso?

functions Saludo(props) {
  return (
    <div
      className='Saludo'
      style={props.style}
    >
      {props.children}
    </div>
  );
}

Analizando un poco el código, vemos como la función Saludo, recibe un objeto de propiedades para ser usadas en el componente, recordemos que el contenido de este ejemplo se convierten en invocaciones a React.createElement(component, props, ...children).

En un ejemplo anterior vimos como asignar valores a las propiedades encerrando expresiones con llaves {}, no solo podemos hacer eso con atributos, sino también para pintar los elementos hijos, ejecutando {props.children}.

El código anterior JSX, se convierte en código JS, así:

functions Saludo(props) {
  return react.createElement("div", {
    className: "Saludo",
    style: props.style
  }, props.children);
}

Ahora que tenemos un componente función, podemos usarlo de las siguientes formas.

const styles = { fontWeight: 'bold', textTransform: 'uppercase' };
const contenido = (
  <div>
   { Saludo({ children: 'Instancia de Saludo' }) }
   {
     Saludo({
       children: 'Instancia de Saludo en negritas',
       style: { fontWeight: 'bold' }
     })
   }
   <Saludo style={styles}>Instancia de Saludo con etiqueta</Saludo>
  </div>
);
const contenedor = document.getElementById('raiz-app');
ReactDOM.render(contenido, contenedor);

Lo mismo, todo este código se convierte a algo como lo siguiente.

functions Saludo(props) {
  return react.createElement("div",
    {
      className: "Saludo",
      style: props.style
    },
    props.children
 );
}
const styles = { fontWeight: 'bold', textTransform: 'uppercase' };
const contenido = react.createElement(
  "div",
  null,
  Saludo({ children: 'Instancia de Saludo' }),
  saludo({
    children: 'Instancia de Saludo en negritas',
    style: {
      fontWeight: 'bold'
    }
  }),
  react.createElement(Saludo, { style: styles }, "Instancia de Saludo con etiqueta")
);
const contenedor = document.getElementById('raiz-app');
ReactDOM.render(contenido, contenedor);

Y el resultado visual es esto.

Resultado de usar un componente reutilizable con React
Resultado de usar un componente reutilizable con React

Date cuenta de que las invocaciones a la función Saludo, así como el uso de la etiqueta Saludo, se convierten en invocaciones a React.createElement(component, props, ...children). Y como el uso del JSX con la etiqueta <Saludo> facilita la lectura y creación del componente. Veamos un ejemplo solo usando etiquetas.

const styles = { fontWeight: 'bold', textTransform: 'uppercase' };
const contenido = (
  <div>
   <Saludo>Instancia de Saludo</Saludo>
   <Saludo style={{ fontWeight: 'bold' }}>Instancia de Saludo en negritas</Saludo>
   <Saludo style={styles}>Instancia de Saludo con etiqueta</Saludo>
  </div>
);
const contenedor = document.getElementById('raiz-app');
ReactDOM.render(contenido, contenedor);

¿Qué tal? Mucho más simple ¿Verdad?

Una última cosa, cuando uses etiquetas de los componentes de React, siempre deben empezar con la primera letra Mayúscula, así es como reconoce JSX que debe invocar a una función con ese nombre. De lo contrario se confundiría con las etiquetas normales de HTML y te lanzará un error como el siguiente.

Warning: The tag <saludo> is unrecognized in this browser. If you want to render a React component, start its name with an uppercase letter

References

https://reactjs.org/

https://babeljs.io/

Instalar multiples versiones de node.js con NVM en macOS, Linux y Windows

Instalar multiples versiones de node.js con NVM en macOS, Linux y Windows

Introduction

Si no sabes que es node y nvm, aquí te explicaré que son, para qué sirven y además como instalar node.js con NVM para tener múltiples versiones y ser más productivo a la hora de crear tus paquetes.

¿Qué es node.js?

Tomando la definición del sitio oficial, Node.js®, node es un entorno de ejecución para JavaScript construido con el motor de JavaScript V8 de Chrome. Node.js usa un modelo de operaciones E/S sin bloqueo y orientado a eventos, que lo hace liviano y eficiente. El ecosistema de paquetes de Node.js, npm, es el ecosistema más grande de librerías de código abierto en el mundo.

Vamos a describir la parte que nos interesa, Node.js es un programa, V8 es un motor de javascript de código abierto creado por Google, por lo que también lo hace un programa, V8 está escrito en C++, y la tarea de V8 es tomar código Javascript y convertirlo a código máquina (compilar código), pero lo que lo hace especial para nuestros fines es que puede ser embebido dentro de otros programas, lo que permite que V8 esté embebido en Node.js, V8 por así decirlo es el punto de partida para toda la funcionalidad de Node.js.

Node.js también está escrito en C++ y utiliza la API de V8 para agregarle características y funcionalidades nuevas a Javascript. Estas nuevas funcionalidades permiten tener acceso al sistema de archivos y carpetas, nos permite crear un servidor TCP y http, además de acceso a POSIX, o sea, a toda la funcionalidad del sistema operativo donde se encuentre instalado.

Node.js proporciona la sintaxis Javascript para crear programas que tengan acceso a las características del sistema operativo donde sé está ejecutando.

Cuando instalas node.js viene por default con una herramienta llamada NPM, que es el administrador de paquetes de node, con esta herramienta tú puedes instalar cualquier paquete de JavaScript que necesites.

¿Cómo lo hace? Pues cualquier desarrollador de javascript que siga los lineamientos adecuados puede publicar su librería/paquete, esta publicación genera un registro que internamente utiliza la línea de comandos de NPM para descargar e instalar ese nuevo paquete, además de que actualmente muchísimos paquetes ya registrados que puedes descargar y usar en tus proyectos.

¿Qué es NVM?

Para instalar node.js con NVM en macOS, primero debes tener git instalado para poder correr el comando de instalación de NVM. Ahora bien, ¿Qué es NVM? NVM significa Node Version Manager, y es al administrador de versiones de node, te permite tener múltiples versiones de node en tu computadora, dándote la flexibilidad de cambiar entre versiones y tener tu propio ambiente de trabajo en cada versión.

Puedes tener tú propios paquetes instalados, específicos para diferentes proyectos. Lo que tienes instalado en una versión, no choca con lo que tienes en otra.

Todo esto te da la habilidad de probar diferentes tipos de versiones de tus paquetes. Si estás creando un nuevo paquete y lo quieres probar en las últimas versiones de node.js, lo puedes hacer sin temor a romper lo que ya tienes para otra versión más estable o incluso para versiones más viejitas.

¿Cómo instalamos node.js con NVM en macOS y Linux?

Suponemos que ya tienes instalado git, si no es así, puedes ver como instalar git en macOS aqui.

Ejecuta el siguiente comando en una terminal:

curl -either- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
Instalar nvm en mac o linux
Instalar nvm en mac o linux

Este comando te clonara la última versión estable de NVM en tu directorio ~/.nvm, luego intentara escribir en tu archivo ~/.zshrc either ~/.bashrc el código de abajo. Esto para que NVM se cargue y funcione correctamente al iniciar sesión en tu computadora.

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion

Ahora para ejecutar el código anterior, y nos funcioné desde este momento nvm, ponemos en la consola el siguiente comando. Esto te permite no cerrar y volver abrir tu shell.

source ~/.zshrc

Revisa si tu instalación de NVM quedo correcta, ejecutando:

nvm --version

Si te imprime la versión, es que todo quedo correctamente instalado.

Ahora instala la última versión estable de node.js con el comando nvm install version

nvm install node # Aqui "node" es una alias para instalar la ultima version

Y verifica la versión de node instalada con:

node --version

¿Como usar otras versiones de node.js con NVM en macOS y Linux?

Para listar todas las versiones de node.js, puedes ejecutar el siguiente comando:

nvm ls-remote

La terminal te mostrará algo así:

nvm ls-remote
nvm ls-remote

Si quieres instalar otra versión, vuelves a ejecutar el comando nvm install version, por ejemplo, vamos a instalar la versión 14:

nvm install 14

Este comando te instalará la versión 14 de node, pero para poder usarlo, debemos ejecutar el siguiente comando:

nvm use 14

Ahora que se instaló la version 14 de node, siempre que se instala una nueva versión, nvm toma como default esa versión recientemente instalada de node en la shell actual, donde se ejecutó el comando de instalación.

Para poder verificar la versión actual, puedes ejecutar el comando `nvm current`, si quieres ver todas las versiones instaladas ejecuta el comando `nvm ls`, el cual lista las versiones instaladas de node.js

nvm ls
nvm ls

¿Cómo instalar node.js con NVM en windows?

Para instalar node.js en windows existen dos opciones similares a NVM, no son lo mismo, pero cumplen con el objetivo de tener varias versiones de node.js para facilitar tu desarrollo de software.

  • NVS
  • NVM windows

Para usar estos comandos se recomienda hacerlo desde tu power shell de windows con derechos de administrador. También desde una terminal muy buena, y que la puedes descargar del siguiente enlace:

https://cmder.net/

Instalar estas dos herramientas en windows, es mucho más fácil porque tiene sus propios instaladores automáticos.

nvs windows

Primero hay que descargar el instalador del enlace de abajito. NVS de hecho fue creado con inspiracion de NVM y tambien se puede usar en Mac y Linux.

https://github.com/jasongin/nvs/releases

Instalador de NVS
Instalador de NVS

Ahora, la operación confiable de “siguiente”, “siguiente”, “siguiente”, “finalizar”. Una vez instalado, en tu terminal de preferencia ejecuta el comando nvs add [version].

nvs add 16

Y para usar una version especifica de node, simplemente en una terminal, ejecuta el comandp nvs use [version].

nvs use 16

nvm-windows

Para instalar nvm-windows es también muy fácil, solo descárgate el instalador de aquí.

https://github.com/coreybutler/nvm-windows/releases

Luego, ya sabes, la operación confiable de oprimir el botón next hasta que la instalación esté completa.

Los comandos que puedes utilizar son:

Para instalar una versión de node ocupamos el comando:

nvm install v16

Si tienes más de una versión de node, puedes elegir cuál usar, al igual que en linux y MacOS.`

nvm use v16

Listo ya sabes como instalar node.js en tu máquina, ahora sí, tienes todo lo necesario para empezar a desarrollar en javascript.

Tipos de datos en Javascript, lo que no te enseñaron

Data types in Javascript, what they didn't teach you

Introduction

Data types in Javascript are a little different compared to other programming languages like C or JAVA.

JavaScript is a weakly typed language, this means that it is not necessary to define the data type. But it is not that it does not have types, since the data type is defined at run time by Javascript.

This behavior and specification of data types applies to any place where javascript is executed, whether in the browser, in node.js, mongodb, or any tool that uses Javascript.

Now if we analyze the concept of types a little, when you make a sum between numbers in the real world you don't care what type it is, you only care that they can be added, regardless of whether it is an integer or decimal. These subtypes of numbers are still part of the set of real numbers, and are used in real life.

Javascript allows us to apply this thinking and with that we save many type comparisons. There will be times when we have no choice but to convert or compare them, but the less we do it, the simpler our code will be, and therefore easier to understand and faster to execute.

It is said that Javascript has a dynamic data type system, this is because the variables that are created can receive any other type of data at any time, and change type depending on the value they store. What we are really interested in is the value and what we can do with that value, not so much the type.

Later we will see some conversions and comparisons that can confuse and complicate the code, the recommendation is to reduce their use as much as possible. Although we will not see each type in great detail, we will see more important things necessary to use data types in Javascript.

It is useful to know how to define variables and constants, if you do not know how to create a variable or a constant, you can review this information before continuing.

Primitive data types

  • It is one that is not an object
  • It has no methods.
  • They are immutable
  • We have seven guys primitive data in Javascript.
  1. number, numbers like; 1, 0, 18500, 89.95124
  2. BigInt, added in 2020, to represent very, very large integers, 99999999999999n
  3. String, character string like 'Hello' and "Good night".
  4. Boolean, only accept true either false, that is, yes or no.
  5. null, serves to indicate that something is nothing, its only value is null.
  6. undefined, serves to indicate that something is not yet defined.
  7. symbol, added in 2015, with EcmaScript 6

Data Types Objects

All other data types in Javascript are objects. In the section Objects there is the explanation.

number

If I had written this before 2020, I would tell you that there is only one numeric data type, unfortunately (with some exceptions) a new numeric value called BigInt. In this section we will pretend that it does not exist.

number is a value 64 bit float, that is, it is a number double In other programming languages, this is basically the only numeric data type in JavaScript, there are no integers (except for BigInt), decimals, floats or doubles. Its specification is provided by IEEE-754.

The way to define and use them is very simple, you simply write the number, it does not matter if it is integer or decimal, floating point or double, as we mentioned before, all of these will be of type double for javascript. This is the recommended way to define them.

const edad = 33;
const PI = 3.1416;
const descuento = 0.30;
const pesoEnDolares = 0.05; // que tristeza xD!!
edad + descuento; // 33.30, no nos interesa el tipo, solo la suma

As we see in the last line, we can add integers and decimals without any problem, we are not interested in the type, we are interested in the ability to add them.

Float values are known to have a certain precision error when performing arithmetic operations, the most obvious operation being division.

0.2 + 0.1; // es igual a 0.30000000000000004

As we see, it does not give us an exact value of 0.3, to mitigate this you can multiply the values by 100 and then divide the result by 100.

(0.2 * 100 + 0.1 * 100)/100; // es igual a 0.3

NaN

There is a special number called NaN. This value is the error of an operation with numbers.

25 * undefined; // es igual a NaN
25 * {}; // es igual a NaN

Any operation you have NaN as one of its operands, will result in NaN.

25 * NaN; // es igua a NaN
25 + NaN; // es igual a NaN

NaN it is not even equal to NaN

NaN === NaN; // es igual a false
NaN == NaN; // es igual a false

To mitigate this strange behavior, it is recommended to use the method Number.isNaN(), there is also a global function called isNaN(), but due to the implicit functionality of Javascript in wanting to convert between types automatically, it can give us very strange results. So as a recommendation always use Number.isNaN(). This last function checks if the type is number and equal to NaN, any other value will return false.

// Usando funcion global
isNaN('James'); // true --> Esto esta mal, deberia seguir regresando false
// lo que realmente hace es una conversion automatica
const result = number('James'); // NaN
isNaN(result); // true
number.isNaN('343434'); // false
number.isNaN('James'); //false
number.isNaN(1 + undefined); // true

We can see in the first example that the global function returns true when it should be false, this is due to the automatic type conversion that javascript does.

Function Number(value)

You can convert a value to a number using the function Number(value), just be careful because this function can return 0 for many values, as well as NaN.

number('5'); // 5
number(''); // 0
number(undefined); // NaN
number(null); // 0
number('8778jaime'); // NaN
number(false); // 0
number(true); // 1;
number({}); // NaN
number([]); // 0

Number.parseInt and Number.parseFloat

Finally we have the functions Number.parseInt(value) and Number.parseFloat(value), if the value is not a string, then convert it to string using the method .toString() before converting to number.

number.parseInt(''); // NaN
number.parseInt('78.5jaime'); // 78
number.parseInt(78.58977); // 78
number.parseFloat(''); // NaN
number.parseFloat('78.5jaime'); // 78.5

BigInt

This type of value is new, added to the language in 2020, it is used to represent very large integer values, especially for mathematical calculations with very large quantities.

To use this type of data, the letter is added to the number n in the end. This is the recommended way.

const enteroMuyGrante = 999999999999999999999999999999999999999999999999999n;
const otroEnteroMuyGrande = 55555555555555555555555555555555555555555555555n;
const result = enteroMuyGrande * otroEnteroMuyGrande; //

Operations can be performed between the Number type and the BigInt, but because conversion between types can cause loss of precision, it is recommended to only use values BigInt when values greater than 2 are being used53 and only perform operations with values of the same type BigInt.

Another bad news about BigInt is that you cannot use the object's methods on a BigInt value. MathematicsFor example, you cannot use Math.sqrt().

Mathematics.sqrt(99); // 9.9498743710662
Mathematics.sqrt(99999999999999999n); // Uncaught TypeError: Cannot convert a BigInt value to a number

As a final recommendation, do not complicate your life, do not use BigInt unless the problem you want to solve necessarily requires very large integers.

BigInt(value) function

You can convert and create a BigInt with the function BigInt(value)

BigInt('9999999999'); // 9999999999n

Boolean

Boolean is a logical data type, which is represented by only two values. true and false. Very useful for making decisions in our programs. Named after the mathematician George Boole.

Boolean type values can be defined as follows. This is the recommended way

const tieneHijos = true;
const esEstudiante = false;

They are widely used in logical operations, for example:

if (tieneHijos) {
  // Si "si" tiene hijos, preguntar cuantos hijos tiene
} else {
  // si "no"
}
if (esEstudiante) {
  // Si "si" es estuduante, aplicar descuento
} else {
  // si "no"
}

Boolean function(value)

Booleans also have a function Boolean(value), is suitable for creating booleans and explicitly converting a value to Boolean. More details below in the section Values that can generate Booleans.

null

This data type in Javascript is very easy, it is a data that means it is nothing compared to the other data types. In other languages null It refers to a pointer or a memory reference that is empty, but in javascript it is different, it is simply a value that means “nothing".

const nada = null;

undefined

This data type represents something that is not yet defined. It is the automatic value of variables, parameters and properties of objects that have not had a value defined.

let name; // undefined
let edad; // undefined
name === undefined; // true
edad === undefined; // true

symbol

This type of data is primarily used to ensure that its value is unique and immutable. It can be used as object properties to reduce access to those properties and thus avoid unwanted modifications. When we look at the objects in more detail we will see their use in practice.

To create this type of primitive data the function is used Symbol(). It is the only way to create a symbols and it is the recommended one.

const name = symbol('Jaime');
const nombreIgual = symbol('Jaime');
name === nombreIgual; // false

String or string of characters

Strings allow us to save information in text form. They are a sequence of one or more 16-bit, UTF-16 characters. There is no `char` type like in other languages, if you want a character, you simply create a string with a single character. Simple right?

We have three ways to create a string.

Actually you can also create strings with the function String(value) or in constructor form new String(value), but let's not complicate our existence and only use the three below for simplicity:

  1. With single quotes, ''. Recommended if you do not need to evaluate expressions inside.
  2. Double quotation marks, ""
  3. backticks, `` . Recommended if you need to evaluate expressions within.
const name = 'Jaime';
const last name = "Cervantes";
const mother's last name = `Velasco`;

The third way to define Strings, allows us to use expressions within the character string, so it is very useful. For example:

const name = 'Jaime';
const last name = "Cervantes";
const mother's last name = `Velasco`;
const nombreCompleto = `${name} ${last name} ${mother's last name}`; // Jaime Cervantes Velasco

Strings are immutable, when you modify or extend a string a new one is actually generated.

Two character strings can be the same

You can check that two character strings are the same with ===.

"James" === "James"; // true
'James' === "James"; // true
`James` === 'James'; // true

Function String(value)

To convert a value to a string you can use the function String(value).

String(1); // '1'
String(null); // 'null'
String(undefined); // 'undefined'

String.length

The property length of a string is used to know the length of a string of characters, you will see over time that this is useful when working with strings of characters.

const name = 'Jaime Cervantes Velasco';
name.length // 23

Objects

All other data types are objects, a function is an object. A object is a collection of pairs name: value, similar to PHP's “associative arrays”. These pairs of name/value They are called properties, a property is like a variable and can contain any type of value.

Some objects in Javascript:

  • object
  • function
  • array
  • date
  • RegExp
  • Mistake

Primitive Wrapping Objects

Even primitive data types String, Boolean, Number, BigInt and Symbol has its corresponding representation in Object, called enveloping objects. In fact, Javascript implicitly converts this primitive data to objects in order to occupy useful methods and properties. For example the property length of a string of characters.

How were you planning to get the length of a character string? Understanding that a character string is primitive data and has no methods

'Jaime Cervantes Velasco'.length; // 23, el pri
// A groso modo, lo que sucede implictamente al querer obtener lenght:
const nuevoString = new String('Jaime Cervantes Velasco');
nuevoString.length; // 23
(5).toFixed(2); // 5.00
// Igual a groso modo pasa algo asi:
const numero = new number(5);
numero.toFixed(2); // 5.00
false.toString(); // 'false'
// Igual a groso modo pasa algo asi:
const booleano = new Boolean(false);
numero.toString(2); // false
// Estos dos tipos de datos primitivos no permiten el uso de new
(9n).toLocaleString(); // '9'
symbol('Hi').toString(); // 'Symbol(Hi)'

Although the BigInt and Symbol data types do not allow the use of new It does not mean that objects are not created behind, it is clear that javascript wraps them in an object because it allows us to use the methods of the example, toLocaleString and toString.

How to create an object?

To create an object you don't need to create a class, you simply create the object and start using it. The easiest way to create an object is to use the definition called literal object, where you simply open and close keys {}. This is the recommended way.

const vacio = {};
const person = {
  name: 'Jaime',
  apellidos: 'Cervantes Velasco',
  edad: 33,
  getName: functions () {
    return `${this.name} ${this.apellidos}`;
  },
  talk: functions () {
    return `Hola, soy ${this.getName()}, tengo ${this.edad} años.`;
  }
};
const frase = person.talk();
console.log(frase); // 'Hola soy Jaime Cervantes Velasco, tengo 33 años.'

In the example we have an object person, has several properties of different types, its name is a String, his age is a numbergetName and talk are of type function, functions that are members of an object are called methods.

Below are examples of objects.

Accessing properties with square brackets, ['key']

In the previous example we saw how to access the method talk(), this method is still a property and is of type functions. But there is another notation to access properties, using square brackets. Very similar to how the elements of an array are accessed.

person.edad; // regresa 33
persona['edad']; // regresa 33
// obtenemos la funciónn con corcheteds y la invocamos con parentesis
const frase = persona['talk']();
console.log(frase); // 'Hola soy Jaime Cervantes Velasco, tengo 29 años.'

How to create an object functions?

functions printPerson(person) {
  console.log(person.name);
  console.log(person.edad);
}

As the function printPerson It is an object, we can add properties to it without any problem.

printPerson.miPropiedad = 'Mi propiedad de una funcion';
console.log(imprimierPersona.miPropiedad); // 'Mi propiedad de una funcion

How to create an object array?

The recommended way is to simply create them using square brackets [].

const vacio = [];
const numeros = [1, 2, 3, 4, 5, 6];
const animales = ['perro', 'gato', 'caballo'];
const conObjetos = [
  		{
          name: 'Jaime',
          edad: 33
        },
        functions imprimierPersona(person) {
          console.log(person);
        }
	];

Since an array is an object, just like a function, you can also add properties to it.

const numeros = [1, 2, 3, 4, 5, 6];
numeros.miPropiedad = 'Mi propiedad de un arreglo';
console.log(numeros.miPropiedad); // 'Mi propiedad de un arreglo

How to create an object date?

const fecha = new date();
console.log(fecha); // Fri May 28 2021 10:46:27 GMT-0500 (hora de verano central)

As you can imagine, we can also add properties to the date object because it is an object

For now, I hope this gives you an idea of the importance of objects in Javascript and why it deserves a more extensive explanation in a future publication.

Values that can generate a boolean false

There are true values and false values, which when applied to a condition behave like Booleans. This is because Javascript does an implicit type conversion, which can surprise us if we are not careful, so here I leave you the list of values that can return a Boolean false.

  • false
  • null
  • undefined
  • 0
  • 0n
  • NaN
  • "", "", " (empty character string)

All other values, including objects, in a condition or passed to the function Boolean(value) the Boolean returns true. A string with a space " ", came back true, and a string with value "false" also returns true.

Boolean function(value)

There is a global function to create Boolean values, Boolean(value). Where yes worth It's a real one, come back true, otherwise it returns false.

Boolean(false); // false
Boolean(null); // false
Boolean(undefined); // false
Boolean(0); // false
Boolean(0n); // false
Boolean(NaN); // false
Boolean(''); // false
// Todos los demas valores van a regresar true
Boolean(' '); // true
Boolean('false'); // true
Boolean('jaime cervantes'); // true
Boolean({}); // true
Boolean([]); // true;

Under logical conditions

Logical conditions in javascript check without a return expression true either false, they execute an implicit conversion.

if (false) {
} else {
  console.log(false);
}
if (null) {
} else {
  console.log(false);
}
if (undefined) {
} else {
  console.log(false);
}
if (0) {
} else {
  console.log(false);
}
if (0n) {
} else {
  console.log(false);
}
if (NaN) {
} else {
  console.log(false);
}
if ('') {
} else {
  console.log(false);
}
if (' ') {
  console.log(true);
}
if ('false') {
  console.log(true);
}
if ({}) {
  console.log(true);
}
if ([]) {
  console.log(true);
}

Verify types with the operator typeof

This operator allows us to identify the type of data we are working with, useful in case we do not know where the information comes from, or we want to process the data based on its type. The operator returns the lowercase name of the data type.

typeof 5; // 'number
typeof NaN; // 'number'
typeof 99999999999999999999999999999999999999999999999n; // 'bigint'
typeof true; // 'boolean'
typeof null; // 'object', esto es un error que existe desde la primera versión de JS
typeof undefined; // 'undefined'
typeof symbol('simbolo'); // 'symbol'
typeof 'cadena de caracteres'; // 'string'
typeof {}; // 'object'
typeof []; // 'object
typeof new date(); // 'object'
typeof new String('Jaime'); // Object
typeof functions() {} // 'function'
typeof class A {} // 'function'

There is a known bug in javascript, when the typeof operator is executed on null, this one comes back'object'. This bug has existed since the first version of Javascript, Bad things happen when you write code on the run.

If all other non-primitive values are objects, when we use the operator typeof about them, what type of data will you tell us what they are? Exactly, 'object'. Just like in the example above when we pass an object literal, an empty array, a date type object and when we use the surrounding objects of primitives like new String('Jaime').

Existe una excepción en typeof, cuando el valor es una función o una clase, regresara functions. Recuerda, una función en javascript, también es un objeto.

Check types with the method Object.prototype.toString

As we saw, it is somewhat confusing to use the operator typeof, I prefer to use a safer method, it is somewhat strange, but since everything in Javascript is an object and the base object from which all data types in javascript start is object, with the exception of the primitive data (although these in turn have their object version), then we can do something like the following.

object.prototype.toString.call(5); // '[object Number]'
object.prototype.toString.call(NaN); // '[object Number]'
object.prototype.toString.call(99999999999999999999999999999999999999999999999n); // '[object BigInt]'
object.prototype.toString.call(true); // '[object Boolean]'
object.prototype.toString.call(null); // '[object Null]',
object.prototype.toString.call(undefined); // '[object Undefined]'
object.prototype.toString.call(symbol('simbolo')); // '[object Symbol]'
object.prototype.toString.call('cadena de caracteres'); // '[object String]'
object.prototype.toString.call({}); // '[object Object]'
object.prototype.toString.call([]); // '[object Array]'
object.prototype.toString.call(new date()); // '[object Date]'
object.prototype.toString.call(new String('Jaime')); // '[object String]'

From this method, you can create a function that verifies the data type.

functions getTypeOf(worth) {
  const texto = object.prototype.toString.call(worth); // '[object Number]', '[object Boolean]', etc
  const sinPalabraObject = texto.slice(8, -1); // Number, Boolean, Null, Undefined, Symbol, String, etc.
  const tipo = sinPalabraObject.toLowerCase(); // number, boolean, null, undefined, symbol, string, etc.
  return tipo;
}
getTypeOf(1); // 'number'
getTypeOf(new date()); // date
getTypeOf([]); // array

The special property prototype is very important in Javascript, if you have read more than one of my publications, you will have noticed that I have mentioned that Javascript is a multiparadigm and object-oriented programming language based on prototypes, in another publication we will explain in detail the functionality of prototypes in Javascript .

Conclusion

Everything in Javascript is an object, with the exception of primitive types, but as we already saw, when wanting to use them as objects by invoking some method, that is where javascript wraps them (in practice everything is an object).

Any programming language has good things that we can take advantage of, but it can also have strange and confusing things (compared to most modern programming languages), such as the operator typeof and the method Object.prototype.toString, the value NaN, the values that can generate a boolean false, and many other things we didn't see for simplicity's sake. It is up to the programmer to take the best parts and eliminate or mitigate those that do not help us communicate better with our work team, always with a focus on simplifying things.

In the case of creating some type of data in Javascript, the simplest and easiest way to use is simply creating the values that we are going to use. As recommended in previous sections, this way of creating them is called literal.

const numero = 9999.54;
const enteroGrande = 99999999999999n;
const boleano = true;
const nulo = null;
let noDefinido;
const simbolo = symbol('identifier');
const cadenaDeCaracteres = 'Jaime Cervantes Velasco';
const cadenaDeCaractresConExpresion = `El numero ${numero} es "Number"`;
const object = {};
const arreglo = [];

There are even more details to cover about data types in javascript, but as we go we will see more necessary topics, for now it seems to me that this information is enough.

Paradigma de programación en JavaScript

JavaScript programming paradigm

What is a programming paradigm?

The model or map of how we see the real world, that is a paradigm, it is a way of seeing and doing things. Following this logic, a programming paradigm is nothing more than a way of viewing and creating programming code.

Paradigms are powerful because they create the glasses or lenses through which we see the world.

Stephen R. Covey

There are three main programming paradigms used today and in JavaScript they have always existed since its first version.

  • Structured programming paradigm
  • Object-oriented
  • Functional

Now, if we stick to the phrase of Stephen R. Covey, that paradigms create the lenses through which we see the world. Let's imagine that the three previous paradigms, each, are a pair of glasses that we put on when programming and that we can change those glasses according to our visual needs (for programming or problem solving).

Structured programming paradigm

Origin

In 1954 the FORTRAN programming language appeared, then in 1958 ALGOL and in 1959 COBOL. Time after Edsger Wybe Dijkstra in 1968 discover the structured programming paradigm, we say “discover” because they didn't actually invent it. Although this programming paradigm was formalized some time after the appearance of these programming languages, it was possible to do structured programming in them.

Dijkstra He recognized that programming was difficult, and programmers don't do it very well, which I totally agree with. A program of any complexity has many details for the human brain. In fact, the Neuroscience tells us that the focused mind It can only work with four pieces of data at a time, at most. For this reason, if one small detail is neglected, we create programs that seem to work well, but fail in ways you never imagine.

Evidence

Dijkstra's solution was to use tests, only these tests used a lot of mathematics, which was quite difficult to implement. During his research he found that certain uses of GOTO made it difficult to decompose a large program into smaller pieces, it could not be applied “divide and conquer”, necessary to create reasonable evidence.

Sequence, selection and iteration

Patrones de la programación estructurada
Patterns of structured programming

Böhm and Jacopini They proved two years earlier that all programs can be built by just three structures: sequence, selection and iteration. Dijkstra already knew these three structures and discovered that these are the ones necessary to make any part of the program tested. This is where the structured programming paradigm is formalized.

Edsger tells us that it is bad practice to use GOTO and suggests better using the following control structures:

  • If, then, else (selection)
  • do, while, until (iteration or repetition)

Decomposition of small units easy to test

Nowadays most programming languages use structured programming, JavaScript uses this type of programming. The simplest example is if conditions.

const EDAD_MINIMA = 18;
if (edad >= EDAD_MINIMA) {
	// hacer algo porque es mayor que 18
} else {
	// Hacer otra cosa en caso contraio
}

And if we isolate it in a function, we have a decomposition of functionalities or units that can be tested more easily. In the next section we will see the importance of having a completely probable unit

const EDAD_MINIMA = 18;
functions esMayorEdad(edad) {
  if (edad >= EDAD_MINIMA) {
     return true;
  } else {
     return false;
  }
}

With this condition we have direct control of what can happen if the age is greater than or equal to 18, and also in the event that the age is younger.

Let's not be so strict either, surely the GOTO ruling has its merits and perhaps it was very efficient in some cases, but I think that to avoid misuses that probably caused disasters, Dijkstra recommended to stop using GOTO.

Test, divide and conquer

Structured programming allows us to apply the “divide and conquer” philosophy, because we allows you to create small unit tests, until the entire program is covered. The mathematical solution of Wybe Dijkstra It was never built, precisely because of its difficulty in implementation. And unfortunately today there are still programmers who do not believe that formal tests are useful for create high quality software.

And I say create, because verify correct operation after create, is nothing more than a simple measurement and the opportunity to reduce time and money is lost.

Scientific method, experiments and impiricism

Método científico, experimentos y pruebas
Scientific method, experiments and tests, by ThisIsEngineering Raeng on unsplash

The good news is that the mathematical method is not the only way to verify our code, we also have the scientific method. Which cannot prove that things are absolutely correct from a mathematical point of view. What we can do is create experiments and obtain enough results to verify that our theories work. Since our theories work on these experiments, then we conclude that they are “correct” enough for our validation purposes.

If the theory is easily validated as false, then it is time to modify or change it. This is the scientific method and this is how tests are currently done:

First we establish our theory (write the test), then we build the experiments (write production code) and finally we verify (run the test) and repeat this cycle until we have enough evidence.

Doesn't this sound like a current agile practice called TDD?

Tests show the presence, not the absence, of defects

Edsger Wybe Dijkstra said “Testing shows the presence, not the absence, of defects.” That is, a program can be proven wrong by testing, but it cannot be proven correct. All we can do with our tests is validate that our program works well enough for our goals. But we can never be one hundred percent sure of the absence of defects.

If we can never be one hundred percent sure that our code is correct, even with its tests, what makes us think that without tests we deliver a program with sufficient validity to affirm that no negligence is consciously committed?

direct control

lto structured programming teaches us about direct control, that is, controlling the sequential flow of operations through the control structures, without neglecting the recommendation of Wybe Dijkstra about GOTO. This recommendation also applies to statements that drastically change the normal flow of operations, for example a break within a cycle for nested, that break It breaks direct control because it abruptly complicates the understanding of the algorithm. Let's not be purists either, there will surely be cases where you need these sentences, but in the first instance, try to avoid them.

In conclusion, the structured programming paradigm teaches us:

The direct, clear and explicit control of what a piece of code does

Object-oriented programming paradigm

Arised from functions?

The object-oriented programming paradigm was discovered in 1966 by Ole Johan Dahl and Kristen Nygaard when they were developing simula 67. Two years before structured programming and its adoption by the programming community was some time later. In 1967 it was launched Simulates 67, Simulates It was the first object-oriented programming language, it basically added classes and objects to ALGOL, initially Simula was going to be a kind of extension of ALGOL.

During the development of Simula, it was observed that the execution of an ALGOL function requires certain data, which could be moved to a tree structure. This tree structure is a Heap.

The heap allowed you to declare local variables of the function that can exist even after the function returns a value. Doesn't this last sound like what closure is in JavaScript?

The parent function becomes a constructor, the local variables become the properties, and the child (nested) functions become its methods. In fact, this pattern is still widely used by Javascript to create modules and use functional inheritance. This also describes how classes work in Javascript, behind are functions.

Spread of polymorphism

All this helped a lot to implement polymorphism in object-oriented programming languages. Ole Johan Dahl and Kristen Nygaard invented the notation:

object.function(parametro)

The execution of function that belongs to object, but more importantly, we pass a message through parameters from the first part of the code to the second part located in a different object.

Molecular biology and message passing

Paso de mensajes entre células
Passing messages between cells, Image modified from “Signaling molecules and cellular receptors: Figure 1,” by OpenStax College, Biology (CC BY 3.0).

Some time later it was created Smalltalk, a much more sophisticated and modern object-oriented programming language, in charge of this project was Alan Kay. This person is credited with the formal definition of object-oriented programming.

The main influence on Alan Kay's object-oriented programming was biology, he has a degree in biology. Although it is obvious that it was influenced by Simula, the influence of LISP (functional programming language) is not so obvious.

From the beginning he thought of objects as interconnected cells in a network, from which they could communicate through messages.

Alan Kay commented:

I'm sorry I coined the term a long time ago. Objects for programming because it made people focus on the least important part. The big idea is “Sending messages“.

Alan Kay

My English is bad so you can check the original text here.

Better object composition over class inheritance

Smalltalk It also allowed the creation of Self, created at Xerox Parc and later migrated to Sun Microsystems Labs. It is said that Self It is an evolution of smalltalk.

In this programming language the idea of prototypes, eliminating the use of classes to create objects, this language uses the objects themselves to allow one object to reuse the functionalities of another.

Self It is a fast language and is generally known for its great performance, self It did a good job on garbage collection systems and also used a virtual machine to manage its execution and memory.

The virtual machine Java HotSpot It could be created thanks to Self. Lars Bak one of Self's latest contributors, he was in charge of creating the V8 Javascript engine. Due to the influence of Self we have today the engine of JavaScript V8, which uses it node.js, mongoDB and Google Chrome internally.

Self followed one of the book's recommendations Design Patterns: Elements of Reusable Object-Oriented Software, long before it came out, published this recommendation:

Better composition of objects to class inheritance.

Design Patterns: Elements of Reusable Object-Oriented Software

Example

Currently Javascript uses prototypes for code reuse, you could say that it uses composition, instead of inheritance. Let's look at an example:

const person = {
    greet () {
      return 'Hola'
    }
};
// se crea un programador con el prototipo igual al objeto persona
const programmer = object.create(persona);
programmer.programar  = () => 'if true';
const saludo = programmer.greet();
const codigo = programmer.programar();
console.log(saludo); // 'Hola'
console.log(codigo); // 'if true'

The object programmer It is based on the prototype of `person`. It doesn't inherit, it just directly reuses the functionality of `person`.

JavaScript emerged shortly after JAVA, in the same year. JavaScript took influences from Self, and in turn Self was influenced by smalltalk.

The syntax of current classes in Javascript is nothing more than a facade, well a little more accurately they are an evolution of the constructor functions, but internally, their basis are functions and prototypes.

Communication with message passing

As we already saw, the origin of object-oriented programming has its origins in functions, and the main idea has always been communication between objects through message passing. We can say that Object-oriented programming tells us of message passing as a key piece for the communication of objects, for example, when a method of one object invokes the method of another.

object.function(parametro);

In conclusion, the object-oriented programming paradigm teaches us:

Message passing for communication between objects

Functional programming paradigm

lambda calculation

Image taken from https://www.slideshare.net/FASTPresentations/introduction-to-lambda-calculus-using-smalltalk-by-facundo-javier-gelatti

Functional programming is the oldest programming paradigm, in fact its discovery was long before computer programming, it was discovered in 1936 by Alonzo Church, when I invented the lambda calculus, based on the same problem to be solved by your student Alan Turing.

As a curious fact, the symbol of the lambda calculus is:

λ

The first language based on functional programming was LISP, created by John McCarthy. As we saw previously, Alan Kay also took influence from LISP to create Smalltalk, with this we can see that the programming paradigms can be united and their relationship between them arises from the idea of how to solve problems more efficiently, they are not fighting, nor Separated, they seek the same goal and somehow evolve together.

The basis of the lambda calculus is immutability, We will review this concept later.

Similarities with OO and structured paradigms

As we saw in the structured programming paradigm, we can decompose our programs into smaller units called procedures or functions. Since functional programming is the oldest paradigm, we can say that the structured programming paradigm also relies on functional programming.

Now, if we analyze the notation a little object.function(x) that we saw in the object-oriented programming paradigm section, is not very different from function(object, parameters), these two lines below are the same, the fundamental idea is the passing of messages, as Alan Kay tells us.

object.function(parametro);
function(objeto, parametro);

Smalltalk uses the “The Actor Model”, which says that actors communicate with each other through messages.

On the other hand we have LISP, which has a “Function dispatcher model” What we currently call functional language, these models are identical, because what functions and methods do is send messages between actors.

An example of this is when a function calls another function or when an object's method is invoked, what happens is that actors exist and they communicate with each other through messages.

Message passing again

So we can emphasize that the main idea of OOP is the sending of messages and that it is not very different from functional programming, in fact according to what we already established in the previous sections, OOP was born from a functional base. And here it is important to highlight what he said Alan Kay Co-creator of SmallTalk:

I'm sorry I coined the term a long time ago. Objects for programming because it made people focus on the least important part. The big idea is “Sending messages“.

Alan Kay

From the communication models between Smalltalk and LISP messages, it was created scheme.

scheme has the goodness to use tail recursion and closure to obtain a functional language, closure allows access to the variables of an external function even when it has already returned a value. This is the same principle that gave rise to object-oriented programming by Ole Johan Dahl and Kristen Nygaard. Do you remember the closure question in Javascript?

Javascript uses closure a lot in its functional programming paradigm. JavaScript took influences from scheme, at the same time scheme was influenced by LISP.

No side effects

The basis of the lambda calculus is immutability, therefore, lImmutability is also the basis of the functional programming paradigm.

We as functional programmers must follow this principle and limit object mutations as much as possible to avoid side effects.

I repeat, the main idea of functional programming is immutability, which allows you to create your programs with fewer errors by not producing side effects that are difficult to control.

As an example, suppose we have an object person and we want to “change” the name, the most obvious thing would be to modify the name property directly, but what happens if that object is used elsewhere and the name is expected to be “Jaime”, that is why instead of changing the name property , we only create a new person object with a different name, without modifying the original.

functions cambiarNombre(name, person) {
  return {
    name: name,
    edad: person.edad
  }
}
const James = { name: 'Jaime', edad: 30 };
const juan = cambiarNombre('Juan', jaime);
console.log(jaime); // { nombre: 'Jaime', edad: 30 }
console.log(juan); // { nombre: 'Juan', edad: 30 }

Here you will find more details about the fundamental principles of functional programming:

Introduction to functional programming

Finally, the functional programming paradigm teaches us:

No side effects, for clear expression and less prone to errors

Conclusion

It is important to note that if the three programming paradigms were implemented between 1958 with LISP (functional programming) and Simula (object-oriented programming) in 1966, and the discovery of the structured programming paradigm in 1968, in only a period of 10 For years there has been innovation in programming paradigms, and new paradigms have not really emerged, unless they are based on these three main ones.

Right now more than 60 years have passed, which tells us the importance and firmness they have despite the time that has passed.

  • Functional programming paradigm (1958, already implemented in a programming language for computers, remember that it was discovered in 1936)
  • Object Oriented (1966)
  • Structured (1968)

The implementation of these three paradigms from the beginning within JavaScript has made this programming language the global success it is today. And it proves to us the value of combining paradigms when writing our programs.

JavaScript is a multi-paradigm programming language, so you can combine the paradigms to create much more efficient and expressive code using:

  • The direct, clear and explicit control of what a piece of code does
  • Message passing for communication between objects
  • No side effects, for clear expression and less prone to errors

References

https://en.wikipedia.org/wiki/Structured_programming

https://en.wikipedia.org/wiki/Structured_program_theorem

http://wiki.c2.com/?AlanKayOnMessaging

https://www.slideshare.net/FASTPresentations/introduction-to-lambda-calculus-using-smalltalk-by-facundo-javier-gelatti

Clean architecture book

en_USEN