10 conceptos de JavaScript que todo desarrollador de Node.js debe dominar

Rahul Mhatre es un líder del equipo de desarrolladores en Software AG.

Con JavaScript y el motor V8 en el núcleo, una arquitectura impulsada por eventos y una escalabilidad lista para usar, Node.js se ha convertido rápidamente en el estándar de facto para crear aplicaciones web y productos SaaS. Los marcos de Node.js, como Express, Sails y Socket.IO, permiten a los usuarios iniciar rápidamente aplicaciones y centrarse solo en la lógica empresarial.

Node.js le debe mucho a JavaScript por su enorme popularidad. JavaScript es un lenguaje multiparadigma que admite muchos estilos diferentes de programación, incluida la programación funcional, la programación procedimental y la programación orientada a objetos. Permite al desarrollador ser flexible y aprovechar los distintos estilos de programación.

Pero JavaScript puede ser un arma de doble filo. La naturaleza multiparadigma de JavaScript significa que casi todo es mutable. Por lo tanto, no puede dejar de lado la probabilidad de mutación de objeto y alcance al escribir código Node.js. Debido a que JavaScript carece de optimización de llamadas de cola (que permite que las funciones recursivas reutilicen marcos de pila para llamadas recursivas), es peligroso usar la recursividad para iteraciones grandes. Además de trampas como estas, Node.js es de un solo hilo, por lo que es imperativo que los desarrolladores escriban código asincrónico.

JavaScript puede ser una bendición si se usa con cuidado, o una pesadilla si es imprudente. Seguir reglas estructuradas, patrones de diseño, conceptos clave y reglas básicas te ayudarán a elegir el enfoque óptimo para un problema. ¿Qué conceptos clave deben comprender los programadores de Node.js? A continuación, compartiré los 10 conceptos de JavaScript que creo que son los más esenciales para escribir código Node.js eficiente y escalable.

Vídeo relacionado: consejos y trucos de Node.js

En este video explicativo, aprenda varias técnicas que pueden mejorar su experiencia de desarrollo de Node.

IIFE de JavaScript: expresiones de función invocadas inmediatamente

Una expresión de función invocada inmediatamente (IIFE) es una función que se ejecuta tan pronto como se crea. No tiene conexión con ningún evento o ejecución asincrónica. Puede definir un IIFE como se muestra a continuación:

(función () {

// todo tu código aquí

// ...

}) ();

El primer par de paréntesis function(){...}convierte el código dentro del paréntesis en una expresión. El segundo par de paréntesis llama a la función resultante de la expresión. Un IIFE también se puede describir como una función anónima autoinvocada. Su uso más común es limitar el alcance de una variable creada mediante varo encapsular el contexto para evitar colisiones de nombres.

Cierres de JavaScript

Un cierre en JavaScript es una función interna que tiene acceso al alcance de su función externa, incluso después de que la función externa haya devuelto el control. Un cierre hace que las variables de la función interna sean privadas. A continuación, se muestra un ejemplo sencillo de cierre:

var count = (function () {

    var _counter = 0;

    return function () {return _counter + = 1;}

}) ();

contar();

contar();

contar();

> // el contador ahora es 3

A la variable countse le asigna una función externa. La función externa se ejecuta solo una vez, lo que establece el contador en cero y devuelve una función interna. La _countervariable se puede acceder sólo por la función interna, lo que hace que se comporte como una variable privada.

Prototipos de JavaScript

Cada función de JavaScript tiene una propiedad prototipo que se utiliza para adjuntar propiedades y métodos. Esta propiedad no es enumerable. Permite al desarrollador adjuntar métodos o funciones miembro a sus objetos. JavaScript admite la herencia solo a través de la propiedad del prototipo. En el caso de un objeto heredado, la propiedad del prototipo apunta al padre del objeto. Un enfoque común para adjuntar métodos a una función es usar prototipos como se muestra a continuación:

función Rectángulo (x, y) {

    this._length = x;

    this._breadth = y;

}

Rectangle.prototype.getDimensions = function () {

    return {longitud: this._length, amplitud: this._breadth};

};

Rectangle.prototype.setDimensions = function (len, bred) {

    this._length = len;

    this._breadth = criado;

};

Propiedades privadas de JavaScript, usando cierres

JavaScript le permite definir propiedades privadas usando el prefijo de subrayado como se muestra en el ejemplo anterior. Sin embargo, esto no impide que un usuario acceda directamente o modifique una propiedad que se supone que es privada.

La definición de propiedades privadas mediante cierres le ayudará a resolver este problema. Las funciones miembro que necesitan acceso a propiedades privadas deben definirse en el propio objeto. Puede hacer propiedades privadas usando cierres como se muestra a continuación:

function Rectangle (_length, _breadth) {

     this.getDimensions = function () {

     return {longitud: _longitud, amplitud: _breadth};

     };

     this.setDimension = function (len, bred) {

     _length = len;

    _breadth = criado

    };

}

Patrón de módulo JavaScript

El patrón de módulo es el patrón de diseño más utilizado en JavaScript para lograr un código bien estructurado y poco acoplado. Te permite crear niveles de acceso públicos y privados. A continuación se muestra una forma de lograr un patrón de módulo:

var Dirección = (función () {

  var _direction = 'adelante'

  var changeDirection = function (d) {

          _direction = d;

  }

  return {setDirection: function (d) {

          changeDirection (d);

          console.log (_direction);

          }

  };

}) ();

Direction.setDirection ('hacia atrás'); // Salidas: 'hacia atrás'

console.log (Dirección._dirección);

El patrón de módulo revelador es similar al patrón de módulo en el que las variables y métodos que deben exponerse se devuelven en un objeto literal. El ejemplo anterior se puede escribir utilizando el patrón del módulo revelador de la siguiente manera:

var Dirección = (función () {

  var _direction = 'adelante';

  var _privateChangeDirection = function (d) {

_direction = d;

  }

  regreso {

          setDirection: _privateChangeDirection

  };

}) ();

Elevación de JavaScript

JavaScript mueve las variables y declaraciones de funciones a la parte superior de su alcance antes de la ejecución del código. A esto se le llama izar. Independientemente de dónde coloque la declaración de funciones y variables en su código, el intérprete las mueve a la parte superior de su alcance. Esto puede ser o no donde los desee. De lo contrario, su programa tendrá errores.

Las declaraciones de variables se procesan antes de que se ejecute cualquier código. Irónicamente, las variables no declaradas no existen hasta que se les asigna un valor. Esto hace que todas las variables no declaradas se conviertan en variables globales. Aunque se elevan las declaraciones de función, las expresiones de función no se elevan. JavaScript tiene un orden de prioridad al elevar variables y funciones.

La prioridad se da a continuación de mayor a menor:

  • Asignación variable
  • Declaración de función
  • Declaraciones de variables

Para evitar errores, debe declarar sus variables y funciones al comienzo de cada ámbito. 

Curry de JavaScript

El curry es un método para hacer que las funciones sean más flexibles. Con una función curry, puede pasar todos los argumentos que la función espera y obtener el resultado, o puede pasar solo un subconjunto de argumentos y recibir una función que espera el resto de los argumentos. A continuación se ofrece un ejemplo sencillo de curry:

var myFirstCurry = function (word) {

  función de retorno (usuario) {

            return [palabra, ",", usuario] .join ("");

  };

};

var HelloUser = myFirstCurry ("Hola");

HelloUser ("Rahul"); // Resultado: "Hola, Rahul"

La función curry original se puede llamar directamente pasando cada uno de los parámetros en un conjunto separado de paréntesis uno tras otro como se muestra a continuación:

myFirstCurry ("¡Oye, qué pasa!") ("Rahul"); // Resultado: "¡Oye, qué pasa! Rahul"

Aplicar, llamar y enlazar métodos de JavaScript

Es imprescindible para cualquier desarrollador JavaScript para entender la diferencia entre los call, applyy bindmétodos. Las tres funciones son similares en que su primer argumento es siempre el valor "this", o contexto, que desea dar a la función a la que está llamando al método.

De los tres, calles el más fácil. Es lo mismo que invocar una función mientras se especifica su contexto. He aquí un ejemplo:

var user = {

     nombre: "Rahul Mhatre",

     whatIsYourName: function () {

     console.log (este.nombre);

     }

};

user.whatIsYourName (); // Resultado: "Rahul Mhatre",

var user2 = {

     nombre: "Neha Sampat"

};

user.whatIsYourName.call (usuario2); // Salida: "Neha Sampat"

Tenga en cuenta que applyes casi lo mismo que call. La única diferencia es que pasa argumentos como una matriz y no por separado. Las matrices son más fáciles de manipular en JavaScript, lo que abre una mayor cantidad de posibilidades para trabajar con funciones. Aquí hay un ejemplo usando applyy call:

var user = {

     saludar: "¡Hola!",

     greetUser: function (nombre de usuario) {

     console.log (this.greet + "" + nombre de usuario);

     }

};

var greet1 = {

     greet: "Hola"

};

user.greetUser.call (greet1, "Rahul") // Salida: "Hola Rahul"

user.greetUser.apply (greet1, ["Rahul"]) // Salida: "Hola Rahul"

El bindmétodo le permite pasar argumentos a una función sin invocarla. Se devuelve una nueva función con argumentos delimitados antes de cualquier otro argumento. Aquí hay un ejemplo:

var user = {

     saludar: "¡Hola!",

     greetUser: function (nombre de usuario) {

     console.log (this.greet + "" + nombre de usuario);

}

};

var greetHola = user.greetUser.bind ({saludar: "Hola"});

var greetBonjour = user.greetUser.bind ({saludar: "Bonjour"});

greetHola ("Rahul") // Salida: "Hola Rahul"

greetBonjour ("Rahul") // Salida: "Bonjour Rahul"

Memorización de JavaScript

La memorización es una técnica de optimización que acelera la ejecución de funciones al almacenar los resultados de operaciones costosas y devolver los resultados almacenados en caché cuando se repite el mismo conjunto de entradas. Los objetos JavaScript se comportan como matrices asociativas, lo que facilita la implementación de memorización en JavaScript. Por ejemplo, podemos convertir una función factorial recursiva en una función factorial memorizada como se muestra a continuación:

function memoizeFunction (func) {

  var cache = {};

  función de retorno () {

          var clave = argumentos [0];

          si (caché [clave]) {

          devolver caché [clave];

          }

          else {

          var val = func.apply (esto, argumentos);

          caché [clave] = val;

          return val;

          }

  };

}

var fibonacci = memoizeFunction (función (n)

  return (n === 0);

Sobrecarga del método JavaScript

La sobrecarga de métodos permite que varios métodos tengan el mismo nombre pero diferentes argumentos. El compilador o intérprete determina qué función llamar en función del número de argumentos pasados. La sobrecarga de métodos no se admite directamente en JavaScript. Pero puede lograr algo muy parecido, como se muestra a continuación:

function overloadMethod (objeto, nombre, fn) {

     if (! object._overload) {

    object._overload = {};

     }

     if (! object._overload [nombre]) {

    object._overload [nombre] = {};

    }

     if (! object._overload [nombre] [fn.length]) {

object._overload [nombre] [fn.length] = fn;

    }

     objeto [nombre] = función () {

         if (this._overload [nombre] [argumentos.longitud])

         return this._overload [nombre] [argumentos.longitud] .aplicar (esto, argumentos);

     };

función Estudiantes () {

  overloadMethod (esto, "buscar", función () {

          // Encuentra un estudiante por nombre

  });

overloadMethod (esto, "buscar", función (primero, último) {

          // Encuentra un estudiante por nombre y apellido

  });

}

var estudiantes = nuevos estudiantes ();

estudiantes.find (); // Encuentra todo

estudiantes.find ("Rahul"); // Busca estudiantes por nombre

estudiantes.find ("Rahul", "Mhatre"); // Busca usuarios por nombre y apellido

A medida que se familiarice con Node.js, notará que hay muchas formas de resolver casi todos los problemas. Pero adoptar el enfoque correcto es fundamental. Un enfoque incorrecto dará como resultado múltiples efectos secundarios, como aplicaciones irregulares o con errores o regresiones que lo obligarán a reescribir toda la lógica. Por otro lado, el enfoque correcto sentará las bases para una aplicación robusta, eficiente y escalable.

Los 10 conceptos de JavaScript descritos en este artículo son conceptos básicos que todo desarrollador de Node.js debe conocer. Pero son la punta del iceberg. JavaScript es poderoso y complejo. Cuanto más lo use, más comprenderá cuán vasto es realmente JavaScript. Una mejor comprensión de un lenguaje tan extenso sin duda le ayudará a evitar errores. Mientras tanto, aprenda lo básico correctamente y verá grandes resultados.

Rahul Mhatre es un líder del equipo de desarrolladores en Software AG. Anteriormente fue arquitecto técnico en Built.io, que fue adquirida por Software AG. 

-

New Tech Forum proporciona un lugar para explorar y discutir la tecnología empresarial emergente con una profundidad y amplitud sin precedentes. La selección es subjetiva, basada en nuestra selección de las tecnologías que creemos que son importantes y de mayor interés para los lectores. no acepta material de marketing para su publicación y se reserva el derecho de editar todo el contenido contribuido. Envíe todas sus consultas a [email protected]