Trabajar con las funciones de cadena integradas de JavaScript

En esta guía, veremos las funciones de cadena integradas de JavaScript y cómo utilizarlas, así como algunos consejos y trucos sobre buenas prácticas.

Introducción

Cuando trabaje con cualquier lenguaje de programación, probablemente necesitará alguna funcionalidad que no esté integrada en ese lenguaje de forma nativa. Por lo tanto, los implementará usted mismo o utilizará varios módulos o bibliotecas.

Esto afecta directamente la eficiencia de su aplicación (más uso de memoria, más solicitudes HTTP, etc.). Para evitar esto, los desarrolladores que trabajan en lenguajes de programación avanzados tienen funciones integradas dentro de los lenguajes para ayudar a evitar tener que usar bibliotecas externas para tareas comunes.

Familiarizarse con estas funciones integradas se considera conocimiento fundamental de un idioma, y ​​aún puede llegar bastante lejos solo con las funciones integradas. Por supuesto, lo más probable es que termines usando algunos módulos/bibliotecas para ciertas tareas.

En esta guía para principiantes, echaremos un vistazo a las funciones integradas de JavaScript relacionadas con las cadenas.

Tipos de datos, estructuras y objetos de JavaScript con funciones integradas

En JavaScript, hay ocho tipos de datos:

  1. Cuerda
  2. Número
  3. Booleano
  4. Nulo
  5. Indefinido
  6. Símbolo
  7. Entrada Grande
  8. Objeto

Sin embargo, no todos los tipos de datos tienen una función integrada. Solo se definen en: Cadena, Número y Booleano.

Cuando se trata de Estructuras de datos en JavaScript, las siete estructuras más utilizadas son:

  1. matriz
  2. Apilar
  3. Cola
  4. Lista enlazada
  5. Árbol
  6. Gráfica
  7. tabla hash

Al igual que los tipos de datos, en las estructuras de datos, las funciones integradas solo se definen en una matriz. Finalmente, Objetos en JavaScript también tienen funciones integradas, como Fecha, RegExp y Math.

En esta guía, nos centraremos específicamente en las cadenas.

Funciones de cadena integradas en JavaScript

Una cadena es, como se mencionó anteriormente, uno de los ocho tipos de datos en JavaScript. Es, en esencia, como una matriz (cadena) de caracteres.

Además, vale la pena señalar que las cadenas son inmutables: una vez que se crea un objeto de cadena, no se puede cambiar. Cualquier función de cambio de cadena creará un nuevo objeto de cadena y lo devolverá, en lugar de modificar el original.

Dado el hecho de que las cadenas son solo matrices, puede tratarlas como matrices y recuperar elementos mediante la notación matriz[índice].

Dicho esto, comencemos con las funciones integradas relacionadas con las cadenas.

Encadenar()

toString() es una de las funciones más utilizadas relacionadas con las cadenas. Pertenece a todos los Objects y devuelve una representación de cadena del objeto, convirtiendo efectivamente un objeto de cualquier tipo en su representación de cadena:

1
2
let x = 100;
console.log(x.toString()); // Output: 100

toString() se comportará de manera diferente con cada objeto, dependiendo de su implementación de la función, lo que significa representar ese objeto como una cadena. Además, tenga en cuenta que si cambia cualquier elemento en una operación aritmética a una cadena, JavaScript inferirá que esto es un intento de concatenación:

1
2
3
4
5
6
7
8
let x = 100;
let y = 200;
   
let z1 = x+y;
let z2 = x.toString() + y;
   
console.log(z1); // Output: 300 
console.log(z2); // Output: 100200

Aquí, z1 es de tipo Number ya que estamos sumando variables de tipo Number juntas y z2 es de tipo String ya que la primera variable es de tipo String y y es se transforma internamente en String y se agrega a x. Si desea convertir un resultado aritmético en una cadena, asegúrese de realizar la conversión al final.

concat()

concat() agrega dos cadenas juntas y devuelve una nueva cadena:

1
2
3
4
let x = "some ";
let y = "string";
   
console.log(x.concat(y)); // Output: some string

Esencialmente realiza la misma operación que:

1
2
3
4
let x = "some";
let y = "string";
   
console.log(x+y); // Output: some string

En realidad, se recomienda preferir la función concat() en lugar de los operandos, debido a los beneficios de rendimiento. Sin embargo, no ganará mucho al concatenar una sola cadena: obtendrá un mayor rendimiento para un gran número de cadenas. Vamos a compararlo muy rápido:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
console.time('Concatenating with Operator');
concatWithOperator();
console.timeEnd('Concatenating with Operator');

console.time('Concatenating with Function');
concatWithFunction();
console.timeEnd('Concatenating with Function');

function concatWithOperator() {
    let result = "";
    for (let i = 0; i < 10000; i++) {
      result = result += i;
    }
}

function concatWithFunction() {
    let result = "";
    for (let i = 0; i < 10000; i++) {
      result = result.concat(i);
    }
}

Esto resulta en:

1
2
Concatenating with Operator: 3.232ms
Concatenating with Function: 1.509ms

La función es alrededor de dos veces más rápida en este código. También vale la pena señalar la declaración oficial de MDN, con respecto a los beneficios de rendimiento:

Se recomienda encarecidamente que se utilicen los operadores de asignación (+, +=) en lugar del método concat().

Lo que puede parecer extraño, dado el hecho de que concat() supera a los operadores en las pruebas. ¿Lo que da? Bueno, comparar código como este no es tan fácil como simplemente ejecutarlo y observar los resultados.

Su navegador, su versión, así como el optimizador que utiliza pueden variar de una máquina a otra, y propiedades como esas realmente afectan el rendimiento. Por ejemplo, hemos usado diferentes cadenas en la concatenación, las generadas a partir de la iteración. Si tuviéramos que usar la misma cadena, un optimizador como el V8 de Google optimizaría aún más el uso de la cadena.

Como regla general, pruebe y verifique su propio código en lugar de seguir los consejos al pie de la letra.

toLocaleUpperCase() y toUpperCase()

toLocaleUpperCase() convierte la cadena dada a mayúsculas, respetando la configuración regional utilizada en la máquina que compila el código. Además, puede especificar la configuración regional a través de un argumento de cadena:

1
2
3
4
let word = "Straße";

console.log(word.toUpperCase()) // STRASSE
console.log(word.toLocaleUpperCase('de-DE')) // STRASSE

En la mayoría de los casos, toUpperCase() y toLocaleUpperCase() devolverán el mismo resultado, incluso si no proporciona el especificador de configuración regional. Solo con asignaciones Unicode no estándar, como con el turco, toLocaleUpperCase() producirá resultados diferentes.

toLocaleLowerCase() y toLowerCase()

toLocaleLowerCase() funciona de manera muy similar a toLocaleUpperCase(), pero convierte la cadena a minúsculas. Del mismo modo, toLowerCase() es independiente de la configuración regional. Sin embargo, tenga en cuenta que cierta información se pierde al convertir entre mayúsculas y minúsculas.

Por ejemplo, si convertimos 'Straße' a mayúsculas y luego a minúsculas, perderá cierta información:

1
2
3
4
5
6
let word = "Straße";

upperCase = word.toLocaleUpperCase('de-DE')

console.log(upperCase) // STRASSE
console.log(upperCase.toLocaleLowerCase('de-DE')) // Strasse

Nuevamente, esto se debe a que, en este caso, el alemán sigue el mapeo Unicode estándar, por lo que toLocaleLowerCase() produce el mismo resultado que toLowerCase(), que simplemente cambia cada carácter a su equivalente en minúsculas.

subcadena()

substring(start, end) devuelve una cadena que contiene los caracteres que van desde el índice start de la cadena original hasta el índice end-1 de la cadena original.

1
2
3
let x = "this is some string";
   
console.log(x.substring(3, 7)); // Output: s is

Como puede ver, el índice end no es inclusivo, por lo que la cadena de salida va desde start hasta end-1.

Además, esto, por supuesto, devuelve una nueva cadena, por lo que puede capturarla asignándola a una nueva variable de referencia o simplemente usarla como entrada para una nueva función. La cadena original permanece sin cambios:

1
2
3
4
5
let x = "this is some string";
let y = x.substring(3, 7);
   
console.log(x); // Output: this is some string
console.log(y); // Output: s is

Si intenta substring() con un fin más allá de la longitud de la cadena, simplemente subcadenará todos los caracteres existentes hasta el final:

1
2
let x = "this is some string";
console.log(x.substring(10, 25)); // Output: me string

This function is particularly useful for truncating output or input, or even checking whether a string comienza con or contiene a given substring.

substr(inicio, longitud)

Similar a substring(), la función substr() se genera tomando ciertos caracteres de una cadena original. Aquí especificamos el índice inicio y el tamaño de la subcadena deseada, que es longitud, en lugar del punto final concreto:

1
2
3
let x = "this is some string";
   
console.log(x.substr(3, 4)); // Output: s is

Si la longitud está más allá del alcance de una cadena, simplemente subcadene hasta el final:

1
2
let x = "hello";
console.log(x.substr(3, 10)); // Output: lo

separar()

La función split(separator, limit) divide una cadena en una matriz de cadenas utilizando el separador proporcionado y en un número límite de partes.

1
2
3
let x = "this is some string";
   
console.log(x.split(" ", 4)); // Output: ['this', 'is', 'some', 'string']

Esto puede ser útil para analizar líneas CSV si no está utilizando bibliotecas externas, ya que son valores separados por comas, que se pueden dividir fácilmente a través de la función split (). Sin embargo, cuando se trata de archivos CSV, querrá realizar una validación si no están formateados correctamente.

Por lo general, utilizará bibliotecas para esto, ya que facilitan mucho las cosas.

If you'd like to read more about reading CSV files in JavaScript, read our guides on Leer y escribir CSV con node-csv and Leer y escribir CSV con Node.js.

charAt() y string[index]

La función charAt(index) devuelve el carácter en el index especificado.

1
2
3
let x = "abc123";
   
console.log(x.charAt(2)); // Output: c

Puede usar esto para iterar a través de una cadena y recuperar su contenido, por ejemplo:

1
2
3
4
5
let x = "some string";

for (let i = 0; i < x.length; i++) {
    console.log(x.charAt(i));
}

Lo que resulta en:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
s
o
m
e
 
s
t
r
i
n
g

¿Cuál es la diferencia entre x.charAt(y) y x[y]?

Hay un par de razones por las que podría preferir charAt() sobre la notación de matriz:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
let x = "some string";

// There is no element 5.7
console.log(x[5.7]);

// 5.7 gets rounded down to 5
console.log(x.charAt(5.7));

// The array notation makes it appear as if we can just assign
// new values to elements, even though strings are immutable
x[5] = 'g';
console.log(x);

// With charAt(), it's much more obvious that
// this line doesn't make sense and will throw an exception
x.charAt(5) = 'g';

Sin embargo, una espada de doble filo está oculta en la implementación de la función charAt() - evalúa el índice dado y lo procesa.

Es por eso que 5.7 se redondeó a 5. También realizará este paso de procesamiento para las entradas que en realidad podrían no ser válidas, pero darán la ilusión de que el código funciona bien:

1
2
3
4
5
6
7
let x = "some string";

console.log(x.charAt(true));
console.log(x.charAt(NaN));
console.log(x.charAt(undefined));
console.log(x.charAt([]))
console.log(x.charAt(""))

verdadero se convierte en 1, mientras que falso se convierte en 0. NaN, undefined, una matriz vacía y una cadena vacía también se convierten en 0, por lo que funciona bien, aunque intuitivamente no debería:

1
2
3
4
5
o
s
s
s
s

Por otro lado, usando la notación de matriz más moderna:

1
2
3
4
5
console.log(x[true]);
console.log(x[NaN]);
console.log(x[undefined]);
console.log(x[[]]);
console.log(x[""]);

Estos producen un resultado más intuitivo, que denota una falla de entrada:

1
2
3
4
5
undefined
undefined
undefined
undefined
undefined

índice de()

indexOf(carácter) devuelve el valor de índice de la primera aparición del carácter especificado:

1
2
3
let x = "aaabbb";
   
console.log(x.indexOf("b")); // Output: 3

Si el carácter no existe, se devuelve -1:

1
2
3
let x = "some string";

console.log(x.indexOf('h')); // Output: -1

Opcionalmente, también puede omitir los primeros n caracteres especificando un fromIndex como segundo argumento:

1
2
3
let x = "aaabbb";
   
console.log(x.indexOf("b", 4)); // Output: 4

Aquí, omitimos los primeros 3 caracteres (indexación basada en 0) y comenzamos a contar en el 4. Por cierto, el cuarto carácter es una 'b' que estamos buscando, por lo que se devuelve el índice.

últimoÍndiceDe()

lastIndexOf(character) devuelve el valor de índice de la última aparición del carácter especificado:

1
2
3
let x = "aaabbb";
    
conosle.log(x.lastIndexOf("b")); // Output: 5

Se aplican las mismas reglas que para la función indexOf():

1
2
3
4
5
let x = "aaabbb";
   
console.log(x.lastIndexOf("b")); // Output: 5
console.log(x.lastIndexOf("b", 3)); // Output: 3
console.log(x.lastIndexOf("g")); // Output: -1

El método cuenta hacia atrás desde el final de la cadena, pero si proporcionamos un argumento fromIndex aquí, el índice se cuenta desde la izquierda. En nuestro caso:

1
2
3
//       012345
let x = "aaabbb";
//          ↑ lastIndexOf() start

Y lastIndexOf() cuenta desde 3 hasta 0, ya que hemos establecido fromIndex en 3.

búsqueda()

La función buscar(cadena) busca una cadena y, si la encuentra, devuelve el índice del comienzo de la cadena encontrada:

1
2
3
let x = "JavaScript, often abbreviated as JS, is a programming language that conforms to the ECMAScript specification. JavaScript is high-level, often just-in-time compiled, and multi-paradigm.";
    
console.log(x.search("programming")); // Output: 42

En el caso de múltiples cadenas que se ajusten a la palabra clave de búsqueda, como 'JavaScript', solo se devuelve el índice inicial del primer caso coincidente:

1
2
3
let x = "JavaScript, often abbreviated as JS, is a programming language that conforms to the ECMAScript specification. JavaScript is high-level, often just-in-time compiled, and multi-paradigm.";
    
console.log(x.search("JavaScript")); // Output: 0

Conclusión

JavaScript es un lenguaje ampliamente difundido, que prevalece en la web, y familiarizarse con las funciones integradas fundamentales lo ayudará a evitar el uso de bibliotecas externas innecesarias, cuando puede lograr un resultado en Vanilla JS.

En esta guía, hemos echado un vistazo a las funciones integradas de las cadenas, uno de los tipos de datos más comunes disponibles en JavaScript. .