func`string`
. The function `func` is called automatically, receives the string and embedded expressions and can process them. This is called "tagged templates". This feature makes it easier to implement custom templating, but is rarely used in practice. You can read more about it in the [manual](mdn:/JavaScript/Reference/Template_literals#Tagged_templates).
+Los backticks además nos permiten especificar una "función de plantilla" antes del primer backtick. La sintaxis es: func`string`
. La función `func` es llamada automáticamente, recibe el string y la expresión insertada y los puede procesar. Puedes leer más sobre esto en [docs](mdn:/JavaScript/Reference/Template_literals#Tagged_template_literals). Eso se llama "plantillas etiquetadas". Esta característica hace que sea más fácil rodear strings en plantillas personalizadas u otra funcionalidad, pero es raramente usada.
-## Special characters
+## Caracteres especiales
-It is still possible to create multiline strings with single and double quotes by using a so-called "newline character", written as `\n`, which denotes a line break:
+Es posible crear strings de múltiples líneas usando comillas simples, usando un llamado "carácter de nueva línea", escrito como `\n`, lo que denota un salto de línea:
```js run
-let guestList = "Guests:\n * John\n * Pete\n * Mary";
+let guestList = 'Invitados:\n * Juan\n * Pedro\n * Maria';
-alert(guestList); // a multiline list of guests
+alert(guestList); // una lista de invitados en múltiples líneas
```
-For example, these two lines are equal, just written differently:
+Por ejemplo, estas dos líneas son iguales, solo que escritas en forma diferente:
```js run
-let str1 = "Hello\nWorld"; // two lines using a "newline symbol"
+let str1 = "Hello\nWorld"; // dos líneas usando el "símbolo de nueva línea"
-// two lines using a normal newline and backticks
+// dos líneas usando nueva línea normal y backticks
let str2 = `Hello
World`;
alert(str1 == str2); // true
```
-There are other, less common "special" characters.
+Existen otros tipos de caracteres especiales, menos comunes.
-Here's the full list:
+Esta es la lista completa:
-| Character | Description |
+| Carácter | Descripción |
|-----------|-------------|
-|`\n`|New line|
-|`\r`|Carriage return: not used alone. Windows text files use a combination of two characters `\r\n` to represent a line break. |
-|`\'`, `\"`|Quotes|
-|`\\`|Backslash|
-|`\t`|Tab|
-|`\b`, `\f`, `\v`| Backspace, Form Feed, Vertical Tab -- kept for compatibility, not used nowadays. |
-|`\xXX`|Unicode character with the given hexadecimal unicode `XX`, e.g. `'\x7A'` is the same as `'z'`.|
-|`\uXXXX`|A unicode symbol with the hex code `XXXX` in UTF-16 encoding, for instance `\u00A9` -- is a unicode for the copyright symbol `©`. It must be exactly 4 hex digits. |
-|`\u{X…XXXXXX}` (1 to 6 hex characters)|A unicode symbol with the given UTF-32 encoding. Some rare characters are encoded with two unicode symbols, taking 4 bytes. This way we can insert long codes. |
+|`\n`|Nueva línea|
+|`\r`|Carriage return (retorno de carro): No se usa solo. Los archivos de texto de Windows usan una combinaión de dos caracteres `\r\n` para representar un corte de línea. |
+|`\'`, `\"`|Comillas|
+|`\\`|Barra invertida|
+|`\t`|Tabulación|
+|`\b`, `\f`, `\v`| Backspace, Form Feed, Vertical Tab -- Se mantienen por compatibilidad. No son usados actualmente |
+|`\xXX`|Carácter Unicode con el hexadecimal dado `XX`, por ej. `'\x7A'` es lo mismo que `'z'`.|
+|`\uXXXX`|Un símbolo unicode con el hexadecimal dado `XXXX` en codificación UTF-16, p.ej. `\u00A9` -- es el unicode para el símbolo copyright `©`. Debe ser exactamente 4 dígitos hex. |
+|`\u{X…XXXXXX}` (1 a 6 caracteres hex)|Un símbolo unicode con el hexadecimal dado en codificación UTF-32. Algunos caracteres raros son codificados con dos símbolos unicode, tomando 4 bytes. De esta manera podemos insertar códigos largos. |
-Examples with unicode:
+Ejemplos con unicode:
```js run
-alert( "\u00A9" ); // ©
-alert( "\u{20331}" ); // 佫, a rare Chinese hieroglyph (long unicode)
-alert( "\u{1F60D}" ); // 😍, a smiling face symbol (another long unicode)
+alert('\u00A9'); // ©
+alert('\u{20331}'); // 佫, un raro jeroglífico chino (unicode largo)
+alert('\u{1F60D}'); // 😍, un emoticón sonriendo (otro unicode largo)
```
-All special characters start with a backslash character `\`. It is also called an "escape character".
+Todos los caracteres especiales comienzan con una barra invertida `\`. También conocida como "carácter de escape".
-We might also use it if we wanted to insert a quote into the string.
+También la usamos si queremos insertar una comilla dentro de un string.
-For instance:
+Por ejemplo:
```js run
-alert( 'I*!*\'*/!*m the Walrus!' ); // *!*I'm*/!* the Walrus!
+alert('Yo soy \'Walrus\''); // Yo soy 'Walrus'
```
-As you can see, we have to prepend the inner quote by the backslash `\'`, because otherwise it would indicate the string end.
+Como puedes ver, debimos anteponer un caracter de escape `\` antes de cada comilla ya que de otra manera hubiera indicado el final del string.
-Of course, only to the quotes that are the same as the enclosing ones need to be escaped. So, as a more elegant solution, we could switch to double quotes or backticks instead:
+Obviamente, eso se refiere sólo a las comillas que son iguales a las que están rodeando al string. Por lo que, una solución más elegante sería cambiar a comillas dobles o backticks:
```js run
-alert( `I'm the Walrus!` ); // I'm the Walrus!
+alert(`Yo soy "Walrus"`); // Yo soy "Walrus"
```
-Note that the backslash `\` serves for the correct reading of the string by JavaScript, then disappears. The in-memory string has no `\`. You can clearly see that in `alert` from the examples above.
+Notar que el caracter de escape `\` sirve para la correcta lectura del string por JavaScript, luego desaparece. El string que quedó en la memoria no incluye `\`. Lo puedes ver claramente en el `alert` del ejemplo anterior.
-But what if we need to show an actual backslash `\` within the string?
+¿Pero qué pasa si necesitamos incluir un carácter de escape `\` en el string?
-That's possible, but we need to double it like `\\`:
+Es posible, pero debemos duplicarlo como sigue `\\`:
```js run
-alert( `The backslash: \\` ); // The backslash: \
+alert(`El carácter de escape: \\`); // El carácter de escape: \
```
-## String length
+## Largo del string (String length)
-The `length` property has the string length:
+La propiedad 'length' entrega el largo del string:
```js run
-alert( `My\n`.length ); // 3
+alert(`Mi\n`.length); // 3
```
-Note that `\n` is a single "special" character, so the length is indeed `3`.
+Notar que `\n` es un carácter "especial" único, por lo que el largo es `3`.
-```warn header="`length` is a property"
-People with a background in some other languages sometimes mistype by calling `str.length()` instead of just `str.length`. That doesn't work.
+```warn header="`length` es una propiedad"
+Gente con experiencia en otros lenguajes a veces comete el error de tipear `str.length()` en vez de `str.length`. Eso no funciona.
-Please note that `str.length` is a numeric property, not a function. There is no need to add parenthesis after it.
+Por favor notar que `str.length` es una propiedad numérica, no una función. No hay necesidad de agregar un paréntesis después de ella.
```
-## Accessing characters
+## Accediendo caracteres
-To get a character at position `pos`, use square brackets `[pos]` or call the method [str.charAt(pos)](mdn:js/String/charAt). The first character starts from the zero position:
+Para acceder a un carácter en la posición `pos`, se debe usar paréntesis cuadrados `[pos]` o llamar al método [str.charAt(pos)](mdn:js/String/charAt). El primer carácter comienza desde la posición cero:
```js run
-let str = `Hello`;
+let str = `Hola`;
-// the first character
+// el primer carácter
alert( str[0] ); // H
alert( str.charAt(0) ); // H
-// the last character
-alert( str[str.length - 1] ); // o
+// el último carácter
+alert( str[str.length - 1] ); // a
```
-The square brackets are a modern way of getting a character, while `charAt` exists mostly for historical reasons.
+Los corchetes son una forma moderna de acceder a los caracteres, mientras que `charAt` existe principalmente por razones históricas.
-The only difference between them is that if no character is found, `[]` returns `undefined`, and `charAt` returns an empty string:
+La única diferencia entre ellos es que si no se encuentra un caracter, `[]` devuelve `undefined`, y `charAt` devuelve un string vacío.
```js run
-let str = `Hello`;
+let str = `Hola`;
-alert( str[1000] ); // undefined
-alert( str.charAt(1000) ); // '' (an empty string)
+alert(str[1000]); // undefined
+alert(str.charAt(1000)); // '' (un string vacío)
```
-We can also iterate over characters using `for..of`:
+Podemos además iterar sobre los caracteres usando `for..of`:
```js run
-for (let char of "Hello") {
- alert(char); // H,e,l,l,o (char becomes "H", then "e", then "l" etc)
+for (let char of 'Hola') {
+ alert(char); // H,o,l,a (char se convierte en "H", luego "o", luego "l" etc)
}
```
-## Strings are immutable
+## Strings son inmutables
-Strings can't be changed in JavaScript. It is impossible to change a character.
+Strings no pueden ser modificados en JavaScript. Es imposible modificar un carácter.
-Let's try it to show that it doesn't work:
+Intentémoslo para demostrar que no funciona:
```js run
-let str = 'Hi';
+let str = 'Hola';
str[0] = 'h'; // error
-alert( str[0] ); // doesn't work
+alert(str[0]); // no funciona
```
-The usual workaround is to create a whole new string and assign it to `str` instead of the old one.
+La solución alternativa es crear un nuevo string y asignarlo a `str` en vez de aisgnarlo al anterior.
-For instance:
+Por ejemplo:
```js run
-let str = 'Hi';
+let str = 'Hola';
-str = 'h' + str[1]; // replace the string
+str = 'h' + str[1]; // reemplaza el string
-alert( str ); // hi
+alert( str ); // hola
```
-In the following sections we'll see more examples of this.
+En la sección siguiente veremos más ejemplos de esto.
-## Changing the case
+## Cambiando mayúsculas y minúsuculas
-Methods [toLowerCase()](mdn:js/String/toLowerCase) and [toUpperCase()](mdn:js/String/toUpperCase) change the case:
+Los métodos [toLowerCase()](mdn:js/String/toLowerCase) y [toUpperCase()](mdn:js/String/toUpperCase) cambian los caracteres a minúscula y mayúscula respectivamente:
```js run
-alert( 'Interface'.toUpperCase() ); // INTERFACE
-alert( 'Interface'.toLowerCase() ); // interface
+alert('Interfaz'.toUpperCase()); // INTERFAZ
+alert('Interfaz'.toLowerCase()); // interfaz
```
-Or, if we want a single character lowercased:
+Si queremos un solo caractér en minúscula:
```js
-alert( 'Interface'[0].toLowerCase() ); // 'i'
+alert('Interfaz'[0].toLowerCase()); // 'i'
```
-## Searching for a substring
+## Buscando una subcadena de caracteres
-There are multiple ways to look for a substring within a string.
+Existen muchas formas de buscar por subcadenas de caracteres dentro de una cadena completa.
### str.indexOf
-The first method is [str.indexOf(substr, pos)](mdn:js/String/indexOf).
+El primer método es [str.indexOf(substr, pos)](mdn:js/String/indexOf).
-It looks for the `substr` in `str`, starting from the given position `pos`, and returns the position where the match was found or `-1` if nothing can be found.
+Este busca un `substr` en `str`, comenzando desde la posición entregada `pos`, y retorna la posición donde es encontrada la coincidencia o `-1` en caso de no encontrar nada.
-For instance:
+Por ejemplo:
```js run
-let str = 'Widget with id';
+let str = 'Widget con id';
-alert( str.indexOf('Widget') ); // 0, because 'Widget' is found at the beginning
-alert( str.indexOf('widget') ); // -1, not found, the search is case-sensitive
+alert(str.indexOf('Widget')); // 0, ya que 'Widget' es encontrado al comienzo
+alert(str.indexOf('widget')); // -1, no es encontrado, la búsqueda toma en cuenta minúsculas y mayúsculas.
-alert( str.indexOf("id") ); // 1, "id" is found at the position 1 (..idget with id)
+alert(str.indexOf('id')); // 1, "id" es encontrado en la posición 1 (..idget con id)
```
-The optional second parameter allows us to search starting from the given position.
+El segundo parámetro es opcional y nos permite buscar desde la posición entregada.
-For instance, the first occurrence of `"id"` is at position `1`. To look for the next occurrence, let's start the search from position `2`:
+Por ejemplo, la primera ocurrencia de `"id"` es en la posición `1`. Para buscar por la siguiente ocurrencia, comencemos a buscar desde la posoción `2`:
```js run
-let str = 'Widget with id';
+let str = 'Widget con id';
-alert( str.indexOf('id', 2) ) // 12
+alert(str.indexOf('id', 2)); // 12
```
-If we're interested in all occurrences, we can run `indexOf` in a loop. Every new call is made with the position after the previous match:
+Si estamos interesados en todas las ocurrencias, podemos correr `indexOf` en un bucle. Cada nuevo llamado es hecho utilizando la posición posterior a la encontrada anteriormente:
```js run
-let str = 'As sly as a fox, as strong as an ox';
+let str = 'Astuto como un zorro, fuerte como un buey';
-let target = 'as'; // let's look for it
+let target = 'como'; // busquemos por él
let pos = 0;
while (true) {
let foundPos = str.indexOf(target, pos);
if (foundPos == -1) break;
- alert( `Found at ${foundPos}` );
- pos = foundPos + 1; // continue the search from the next position
+ alert(`Encontrado en ${foundPos}`);
+ pos = foundPos + 1; // continuar la búsqueda desde la siguiente posición
}
```
-The same algorithm can be layed out shorter:
+Podemos escribir el mismo algoritmo pero más corto:
```js run
-let str = "As sly as a fox, as strong as an ox";
-let target = "as";
+let str = 'Astuto como un zorro, fuerte como un buey';
+let target = "como";
*!*
let pos = -1;
@@ -281,232 +281,232 @@ while ((pos = str.indexOf(target, pos + 1)) != -1) {
```
```smart header="`str.lastIndexOf(substr, position)`"
-There is also a similar method [str.lastIndexOf(substr, position)](mdn:js/String/lastIndexOf) that searches from the end of a string to its beginning.
+Existe también un método similar [str.lastIndexOf(substr, position)](mdn:js/String/lastIndexOf) que busca desde el final del string hasta el comienzo.
-It would list the occurrences in the reverse order.
+Este imprimirá las ocurrencias en orden invertido.
```
-There is a slight inconvenience with `indexOf` in the `if` test. We can't put it in the `if` like this:
+Existe un leve inconveniente con `indexOf` en la prueba `if`. No podemos utilizarlo en el `if` como sigue:
```js run
-let str = "Widget with id";
+let str = "Widget con id";
if (str.indexOf("Widget")) {
- alert("We found it"); // doesn't work!
+ alert("Lo encontramos"); // no funciona!
}
```
-The `alert` in the example above doesn't show because `str.indexOf("Widget")` returns `0` (meaning that it found the match at the starting position). Right, but `if` considers `0` to be `false`.
+La `alerta` en el ejemplo anterior no se muestra ya que `str.indexOf("Widget")` retorna `0` (lo que significa que encontró el string en la posoción inicial). Correcto pero `if` considera `0` como `falso`.
-So, we should actually check for `-1`, like this:
+Por lo que debemos buscar por `-1` como sigue:
```js run
-let str = "Widget with id";
+let str = "Widget con id";
*!*
if (str.indexOf("Widget") != -1) {
*/!*
- alert("We found it"); // works now!
+ alert("Lo encontramos"); // ahora funciona!
}
```
-#### The bitwise NOT trick
+#### El truco "bitwise NOT"
-One of the old tricks used here is the [bitwise NOT](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_NOT) `~` operator. It converts the number to a 32-bit integer (removes the decimal part if exists) and then reverses all bits in its binary representation.
+Uno de los antiguos trucos es el operador [bitwise NOT](https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Operadores/Bitwise_Operators#Bitwise_NOT)) `~`. Este convierte el número en un entero de 32-bits (elimina la parte decimal si es que existe) y luego invierte todos los bits en su representación binaria.
-In practice, that means a simple thing: for 32-bit integers `~n` equals `-(n+1)`.
+En la práctica, esto significa una simple cosa: Para enteros de 32 bits, `~n` es igual a `-(n+1)`.
-For instance:
+Por ejemplo:
```js run
-alert( ~2 ); // -3, the same as -(2+1)
-alert( ~1 ); // -2, the same as -(1+1)
-alert( ~0 ); // -1, the same as -(0+1)
+alert( ~2 ); // -3, lo mismo que -(2+1)
+alert( ~0 ); // -1, lo mismo que -(0+1)
+alert( ~1 ); // -2, lo mismo que -(1+1)
*!*
-alert( ~-1 ); // 0, the same as -(-1+1)
+alert( ~-1 ); // 0, lo mismo que -(-1+1)
*/!*
```
-As we can see, `~n` is zero only if `n == -1` (that's for any 32-bit signed integer `n`).
+Como podemos ver, `~n` es cero sólo si `n == -1`. (para cualquier entero de 32-bit con signo).
-So, the test `if ( ~str.indexOf("...") )` is truthy only if the result of `indexOf` is not `-1`. In other words, when there is a match.
+Por lo que, la prueba `if ( ~str.indexOf("...") )` es veraz y el resultado de ``indexOf no es `-1`. En otras palabras, cuando es encontrado.
-People use it to shorten `indexOf` checks:
+La gente lo usa para acortar verificaciones `indexOf`:
```js run
let str = "Widget";
if (~str.indexOf("Widget")) {
- alert( 'Found it!' ); // works
+ alert( 'Lo encontramos!' ); // funciona
}
```
-It is usually not recommended to use language features in a non-obvious way, but this particular trick is widely used in old code, so we should understand it.
+Usualmente no es recomendado utilizar características del lenguaje en formas no obvias, pero en particular, este truco es utilizado ampliamente en código antiguo, por lo que debemos entenderlo.
-Just remember: `if (~str.indexOf(...))` reads as "if found".
+Recuerda: `if (~str.indexOf(...))` es leído como "si es encontrado".
-To be precise though, as big numbers are truncated to 32 bits by `~` operator, there exist other numbers that give `0`, the smallest is `~4294967295=0`. That makes such check is correct only if a string is not that long.
+Para ser preciso, como los números grandes son truncados a 32 bits por el operador `~`, existen otros números que dan `0`, el menor es `~4294967295=0`. Esto hace que tal chequeo sea correcto solo si el string no es así de largo.
-Right now we can see this trick only in the old code, as modern JavaScript provides `.includes` method (see below).
+Ahora podemos ver este truco solo en código viejo, porque JavaScript moderno provee el método `.includes` (ver a continuación).
### includes, startsWith, endsWith
-The more modern method [str.includes(substr, pos)](mdn:js/String/includes) returns `true/false` depending on whether `str` contains `substr` within.
+El método más moderno [str.includes(substr, pos)](mdn:js/String/includes) retorna `true/false` dependiendo si `str` contiene `substr` dentro.
-It's the right choice if we need to test for the match, but don't need its position:
+Es la opción correcta si lo que necesitamos es encontrar el `substr` pero no necesitamos la posición.
```js run
-alert( "Widget with id".includes("Widget") ); // true
+alert('Widget con id'.includes('Widget')); // true
-alert( "Hello".includes("Bye") ); // false
+alert('Hola'.includes('Adios')); // false
```
-The optional second argument of `str.includes` is the position to start searching from:
+El segundo argumento opcional de `str.includes` es la posición desde donde comienza a buscar:
```js run
-alert( "Widget".includes("id") ); // true
-alert( "Widget".includes("id", 3) ); // false, from position 3 there is no "id"
+alert('Midget'.includes('id')); // true
+alert('Midget'.includes('id', 3)); // false, desde la posición 3 no hay "id"
```
-The methods [str.startsWith](mdn:js/String/startsWith) and [str.endsWith](mdn:js/String/endsWith) do exactly what they say:
+Los métodos [str.startsWith](mdn:js/String/startsWith) (comienza con) y [str.endsWith](mdn:js/String/endsWith) (termina con) hacen exactamente lo que dicen:
```js run
-alert( "Widget".startsWith("Wid") ); // true, "Widget" starts with "Wid"
-alert( "Widget".endsWith("get") ); // true, "Widget" ends with "get"
+alert('Widget'.startsWith('Wid')); // true, "Widget" comienza con "Wid"
+alert('Widget'.endsWith('get')); // true, "Widget" termina con "get"
```
-## Getting a substring
+## Obteniendo un substring
-There are 3 methods in JavaScript to get a substring: `substring`, `substr` and `slice`.
+Existen 3 métodos en JavaScript para obtener un substring: `substring`, `substr` y `slice`.
-`str.slice(start [, end])`
-: Returns the part of the string from `start` to (but not including) `end`.
+`str.slice(comienzo [, final])`
+: Retorna la parte del string desde `comienzo` hasta (pero sin incluir) `final`.
- For instance:
+ Por ejemplo:
```js run
let str = "stringify";
- alert( str.slice(0, 5) ); // 'strin', the substring from 0 to 5 (not including 5)
- alert( str.slice(0, 1) ); // 's', from 0 to 1, but not including 1, so only character at 0
+ alert( str.slice(0, 5) ); // 'strin', el substring desde 0 hasta 5 (sin incluir 5)
+ alert( str.slice(0, 1) ); // 's', desde 0 hasta 1, pero sin incluir 1, por lo que sólo el caracter en 0
```
- If there is no second argument, then `slice` goes till the end of the string:
+ Si no existe segundo argumento, entonces `slice` va hasta el final del string:
```js run
let str = "st*!*ringify*/!*";
- alert( str.slice(2) ); // 'ringify', from the 2nd position till the end
+ alert( str.slice(2) ); // ringify, desde la 2nda posición hasta el final
```
- Negative values for `start/end` are also possible. They mean the position is counted from the string end:
+ También son posibles valores negativos para `comienzo/final`. Ellos indican que la posición es contada desde el final del string.
+
```js run
let str = "strin*!*gif*/!*y";
-
- // start at the 4th position from the right, end at the 1st from the right
- alert( str.slice(-4, -1) ); // 'gif'
+ // comienza en la 4ta posición desde la derecha, finaliza en la 1era posición desde la derecha
+ alert( str.slice(-4, -1) ); // gif
```
-`str.substring(start [, end])`
-: Returns the part of the string *between* `start` and `end`.
-
- This is almost the same as `slice`, but it allows `start` to be greater than `end`.
+`str.substring(comienzo [, final])`
+: Devuelve la parte del string _entre_ `comienzo` y `final`.
- For instance:
+ Esto es casi lo mismo que `slice`, pero permite que `comienzo` sea mayor que `final`.
+
+ Por ejemplo:
```js run
let str = "st*!*ring*/!*ify";
- // these are same for substring
+ // esto es lo mismo para substring
alert( str.substring(2, 6) ); // "ring"
alert( str.substring(6, 2) ); // "ring"
- // ...but not for slice:
- alert( str.slice(2, 6) ); // "ring" (the same)
- alert( str.slice(6, 2) ); // "" (an empty string)
+ // ...pero no para slice:
+ alert( str.slice(2, 6) ); // "ring" (lo mismo)
+ alert( str.slice(6, 2) ); // "" (un string vacío)
```
- Negative arguments are (unlike slice) not supported, they are treated as `0`.
+ Los argumentos negativos (al contrario de slice) no son soportados, son tratados como `0`.
-`str.substr(start [, length])`
-: Returns the part of the string from `start`, with the given `length`.
+`str.substr(comienzo [, largo])`
+: Retorna la parte del string desde `comienzo`, con el `largo` dado.
- In contrast with the previous methods, this one allows us to specify the `length` instead of the ending position:
+ A diferencia de los métodos anteriores, este nos permite especificar el `largo` en lugar de la posición final:
```js run
let str = "st*!*ring*/!*ify";
- alert( str.substr(2, 4) ); // 'ring', from the 2nd position get 4 characters
+ alert( str.substr(2, 4) ); // ring, desde la 2nda posición toma 4 caracteres
```
- The first argument may be negative, to count from the end:
+ El primer argumento puede ser negativo, para contar desde el final:
```js run
let str = "strin*!*gi*/!*fy";
- alert( str.substr(-4, 2) ); // 'gi', from the 4th position get 2 characters
+ alert( str.substr(-4, 2) ); // gi, desde la 4ta posición toma 2 caracteres
```
-Let's recap these methods to avoid any confusion:
+Recapitulemos los métodos para evitar confusiones:
-| method | selects... | negatives |
-|--------|-----------|-----------|
-| `slice(start, end)` | from `start` to `end` (not including `end`) | allows negatives |
-| `substring(start, end)` | between `start` and `end` | negative values mean `0` |
-| `substr(start, length)` | from `start` get `length` characters | allows negative `start` |
+| método | selecciona... | negativos |
+| ----------------------- | ------------------------------------------- | ------------------------ |
+| `slice(comienzo, final)` | desde `comienzo` hasta `final` (sin incluir `final`) | permite negativos |
+| `substring(comienzo, final)` | entre `comienzo` y `final` | valores negativos significan `0` |
+| `substr(comienzo, largo)` | desde `comienzo` toma `largo` caracteres | permite negativos `comienzo` |
-```smart header="Which one to choose?"
-All of them can do the job. Formally, `substr` has a minor drawback: it is described not in the core JavaScript specification, but in Annex B, which covers browser-only features that exist mainly for historical reasons. So, non-browser environments may fail to support it. But in practice it works everywhere.
+```smart header="¿Cuál elegir?"
+Todos son capaces de hacer el trabajo. Formalmente, `substr` tiene una pequeña desventaja: no es descrito en la especificación central de JavaScript, sino en el anexo B, el cual cubre características sólo de navegadores, que existen principalmente por razones históricas. Por lo que entornos sin navegador pueden fallar en compatibilidad. Pero en la práctica funciona en todos lados.
-Of the other two variants, `slice` is a little bit more flexible, it allows negative arguments and shorter to write. So, it's enough to remember solely `slice` of these three methods.
+De las otras dos variantes, `slice` es algo más flexible, permite argumentos negativos y es más corta. Entones, es sufuciente con, de estos tres métodos, recordar únicamente `slice`.
```
-## Comparing strings
+## Comparando strings
-As we know from the chapter Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: