Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
8c7b981
Add information about virtual/mobile keyboards and an additional keyb…
Danziger Nov 28, 2020
7b21346
Typos + rephrasing
RapTho Dec 14, 2020
9f2d200
Update 2-ui/3-event-details/7-keyboard-events/article.md
Danziger Dec 14, 2020
9a84c51
Fixed small typos
RapTho Dec 14, 2020
3a21dce
Add link to Kotlin/JS
tokou Dec 16, 2020
1af33d1
Give me five
joaquinelio Dec 20, 2020
5a14316
Update article.md
joaquinelio Dec 20, 2020
fc3f811
Merge pull request #2399 from joaquinelio/patch-2
iliakan Dec 20, 2020
f3555ee
fixed small typos
nazar-bodan Dec 20, 2020
13da056
closes #2401
iliakan Dec 22, 2020
cbdc268
Update article.md
imaverage Dec 24, 2020
33e25dc
Update article.md
Georgy-Losenkov Dec 25, 2020
83b051e
Change source of the term 'microtask'
raycon Dec 31, 2020
701392c
Merge pull request #2413 from raycon/master
iliakan Dec 31, 2020
6418344
closes #2411
iliakan Dec 31, 2020
2754e03
closes #2410
iliakan Dec 31, 2020
1404669
Merge pull request #2406 from Georgy-Losenkov/patch-1
iliakan Dec 31, 2020
b7d2820
Merge pull request #2391 from RapTho/patch-6
iliakan Dec 31, 2020
b0aa994
Merge pull request #2400 from wolfter12/fixed-small-typos
iliakan Dec 31, 2020
1fa08bc
Merge pull request #2404 from imaverage/patch-1
iliakan Dec 31, 2020
cc593c6
Update article.md
LLyaudet Dec 31, 2020
02089cf
Merge pull request #2393 from tokou/patch-1
iliakan Dec 31, 2020
98de4f4
Merge pull request #2386 from RapTho/patch-2
iliakan Dec 31, 2020
4a0da59
Merge pull request #2414 from LLyaudet/patch-2
iliakan Dec 31, 2020
04b1313
Remove keyjs.dev link under the key codes inspection snippet.
Danziger Jan 3, 2021
039716d
Merge pull request #2389 from Danziger/patch-1
iliakan Jan 3, 2021
92f225a
merging all conflicts
iliakan Jan 4, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions 1-js/01-getting-started/1-intro/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,20 @@ Las herramientas modernas hacen la conversión (Transpilation) muy rápida y tra

Ejemplos de tales lenguajes:

<<<<<<< HEAD
- [CoffeeScript](http://coffeescript.org/) Es una "sintaxis azucarada" para JavaScript. Introduce una sintaxis corta, permitiéndonos escribir un código mas claro y preciso. Usualmente desarrolladores de Ruby prefieren este lenguaje.
- [TypeScript](http://www.typescriptlang.org/) se concentra en agregar "tipado estricto" ("strict data typing") para simplificar el desarrollo y soporte de sistemas complejos. Es desarrollado por Microsoft.
-[FLow](https://flow.org/) también agrega la escritura de datos, pero de una manera diferente. Desarrollado por Facebook.
- [Dart](https://www.dartlang.org/) es un lenguaje independiente que tiene su propio motor que se ejecuta en entornos que no son de navegador (como aplicaciones móviles), pero que también se puede convertir/transpilar a JavaScript. Desarrollado por Google.
- [Brython](https://brython.info/) es un transpilador de Python a JavaScript que permite escribir aplicaciones en Python puro sin JavaScript.
=======
- [CoffeeScript](http://coffeescript.org/) is a "syntactic sugar" for JavaScript. It introduces shorter syntax, allowing us to write clearer and more precise code. Usually, Ruby devs like it.
- [TypeScript](http://www.typescriptlang.org/) is concentrated on adding "strict data typing" to simplify the development and support of complex systems. It is developed by Microsoft.
- [Flow](http://flow.org/) also adds data typing, but in a different way. Developed by Facebook.
- [Dart](https://www.dartlang.org/) is a standalone language that has its own engine that runs in non-browser environments (like mobile apps), but also can be transpiled to JavaScript. Developed by Google.
- [Brython](https://brython.info/) is a Python transpiler to JavaScript that enables the writing of applications in pure Python without JavaScript.
- [Kotlin](https://kotlinlang.org/docs/js-overview.html) is a modern, concise and safe programming language that can target the browser or Node.
>>>>>>> 039716de8a96f49b5fccd7aed5effff2e719dfe5

Hay más. Por supuesto, incluso si nosotros usamos alguno de estos lenguajes, deberíamos conocer también JavaScript para realmente entender qué estamos haciendo.

Expand Down
4 changes: 4 additions & 0 deletions 1-js/04-object-basics/07-optional-chaining/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,4 +219,8 @@ Como podemos ver, todos ellos son sencillos y fáciles de usar. El `?.` comprueb

Una cadena de `?.` permite acceder de forma segura a las propiedades anidadas.

<<<<<<< HEAD
Aún así, debemos aplicar `?.` con cuidado, solo donde está bien que la parte izquierda no exista. Para que no nos oculte errores de programación, si ocurren.
=======
Still, we should apply `?.` carefully, only where it's acceptable that the left part doesn't exist. So that it won't hide programming errors from us, if they occur.
>>>>>>> 039716de8a96f49b5fccd7aed5effff2e719dfe5
8 changes: 8 additions & 0 deletions 1-js/05-data-types/02-number/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,11 @@ JavaScript tiene un objeto incorporado [Math](https://developer.mozilla.org/es/d
Unos ejemplos:

`Math.random()`
<<<<<<< HEAD
: Devuelve un número aleatorio entre 0 y 1 (no incluyendo 1)
=======
: Returns a random number from 0 to 1 (not including 1).
>>>>>>> 039716de8a96f49b5fccd7aed5effff2e719dfe5

```js run
alert( Math.random() ); // 0.1234567894322
Expand All @@ -400,7 +404,11 @@ Unos ejemplos:
```

`Math.pow(n, power)`
<<<<<<< HEAD
: Devuelve `n` elevado a la potencia `power` dada
=======
: Returns `n` raised to the given power.
>>>>>>> 039716de8a96f49b5fccd7aed5effff2e719dfe5

```js run
alert( Math.pow(2, 10) ); // 2 elevado a la potencia de 10 = 1024
Expand Down
4 changes: 4 additions & 0 deletions 1-js/05-data-types/06-iterable/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@ Pero un iterable puede no ser array-like. Y viceversa, un array-like puede no se

Por ejemplo, `range` en el ejemplo anterior es iterable, pero no array-like, porque no tiene propiedades indexadas ni `longitud` o *length*.

<<<<<<< HEAD
=======
But an iterable may be not array-like. And vice versa an array-like may be not iterable.
>>>>>>> 039716de8a96f49b5fccd7aed5effff2e719dfe5

Y aquí está el objeto que tiene forma de matriz, pero no es iterable:

Expand Down
13 changes: 13 additions & 0 deletions 1-js/06-advanced-functions/04-var/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,11 @@ if (true) {
}

*!*
<<<<<<< HEAD
alert(test); // Error: test no está definido
=======
alert(test); // ReferenceError: test is not defined
>>>>>>> 039716de8a96f49b5fccd7aed5effff2e719dfe5
*/!*
```

Expand Down Expand Up @@ -82,7 +86,11 @@ function sayHi() {
}

sayHi();
<<<<<<< HEAD
alert(phrase); // Error: phrase no está definida
=======
alert(phrase); // ReferenceError: phrase is not defined
>>>>>>> 039716de8a96f49b5fccd7aed5effff2e719dfe5
```

Como podemos ver, `var` atraviesa `if`, `for` u otros bloques. Esto es porque mucho tiempo atrás los bloques en JavaScript no tenían ambientes léxicos. Y `var` es un remanente de aquello.
Expand Down Expand Up @@ -230,8 +238,13 @@ Aquí la expresión de función es creada e inmediatamente llamada. Entonces el
La expresión de función es encerrada entre paréntesis `(function {...})`, porque cuando JavaScript se encuentra con `"function"` en el flujo de código principal lo entiende como el principio de una declaración de función. Pero una declaración de función debe tener un nombre, entonces ese código daría error:

```js run
<<<<<<< HEAD
// Trata de declarar e inmediatamente llamar una función
function() { // <-- Error: la instrucción de función requiere un nombre de función
=======
// Tries to declare and immediately call a function
function() { // <-- SyntaxError: Function statements require a function name
>>>>>>> 039716de8a96f49b5fccd7aed5effff2e719dfe5

var message = "Hello";

Expand Down
15 changes: 15 additions & 0 deletions 1-js/11-async/05-promise-api/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ En la práctica este método casi nunca es usado.

## Resumen

<<<<<<< HEAD
Existen 6 métodos estáticos de la clase `Promise`:

1. `Promise.all(promises)` -- espera que todas las promesas se resuelvan y devuelve un array de sus resultados. Si cualquiera es rechazada se vuelve el error de `Promise.all` y los demás resultados son ignorados.
Expand All @@ -321,3 +322,17 @@ Existen 6 métodos estáticos de la clase `Promise`:
6. `Promise.reject(error)` -- crea una promesa rechazada con el "error" dado.

`Promise.all` es probablemente el más común en la práctica.
=======
There are 6 static methods of `Promise` class:

1. `Promise.all(promises)` -- waits for all promises to resolve and returns an array of their results. If any of the given promises rejects, it becomes the error of `Promise.all`, and all other results are ignored.
2. `Promise.allSettled(promises)` (recently added method) -- waits for all promises to settle and returns their results as an array of objects with:
- `status`: `"fulfilled"` or `"rejected"`
- `value` (if fulfilled) or `reason` (if rejected).
3. `Promise.race(promises)` -- waits for the first promise to settle, and its result/error becomes the outcome.
4. `Promise.any(promises)` (recently added method) -- waits for the first promise to fulfill, and its result becomes the outcome. If all of the given promises are rejected, [`AggregateError`](mdn:js/AggregateError) becomes the error of `Promise.any`.
5. `Promise.resolve(value)` -- makes a resolved promise with the given value.
6. `Promise.reject(error)` -- makes a rejected promise with the given error.

Of all these, `Promise.all` is probably the most common in practice.
>>>>>>> 039716de8a96f49b5fccd7aed5effff2e719dfe5
8 changes: 8 additions & 0 deletions 1-js/11-async/07-microtask-queue/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ Es algo extraño, porque la promesa se realiza por completo desde el principio.

## Cola de microtareas (Microtasks queue)

<<<<<<< HEAD
Las tareas asincrónicas necesitan una gestión adecuada. Para ello, el estándar ECMA especifica una cola interna `PromiseJobs`, en ocasiones más conocida como "cola de microtareas" (término ES8).
=======
Asynchronous tasks need proper management. For that, the ECMA standard specifies an internal queue `PromiseJobs`, more often referred to as the "microtask queue" (V8 term).
>>>>>>> 039716de8a96f49b5fccd7aed5effff2e719dfe5

Como se indica en la [especificación](https://tc39.github.io/ecma262/#sec-jobs-and-job-queues):

Expand Down Expand Up @@ -103,7 +107,11 @@ En el ejemplo anterior, `.catch` agregado por `setTimeout` también se dispara.

## Resumen

<<<<<<< HEAD
El control de promesas siempre es asíncrono, ya que todas las acciones de promesa pasan por la cola interna de "PromiseJobs", también llamada "cola de microtareas" (término ES8).
=======
Promise handling is always asynchronous, as all promise actions pass through the internal "promise jobs" queue, also called "microtask queue" (V8 term).
>>>>>>> 039716de8a96f49b5fccd7aed5effff2e719dfe5

Entonces, los controladores `.then/catch/finally` siempre se llaman después de que el código actual ha finalizado.

Expand Down
2 changes: 2 additions & 0 deletions 1-js/11-async/08-async-await/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ Pero podemos envolverlo dentro de una función async anónima, como esto:
...
})();
```

P.S. The notable exception is V8 engine version 8.9+, where top-level await works in [modules](info:modules).
````

````smart header="*await* acepta \"thenables\""
Expand Down
4 changes: 4 additions & 0 deletions 2-ui/1-document/04-searching-elements-dom/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,11 @@ Por ejemplo:

Los *ancestros* de un elmento son: el padre, el padre del padre, su padre y así sucesivamente. Todos los ancestros juntos forman la cadena de padres desde el elemento hasta la cima.

<<<<<<< HEAD
El método `elem.closest(css)` busca el ancestro más cercano que coincide con el selector CSS. El propio `elem` también se incluye en la búsqueda.
=======
The method `elem.closest(css)` looks for the nearest ancestor that matches the CSS-selector. The `elem` itself is also included in the search.
>>>>>>> 039716de8a96f49b5fccd7aed5effff2e719dfe5

En otras palabras, el método `closest` sube del elemento y comprueba cada uno de los padres. Si coincide con el selector, entonces la búsqueda se detiene y devuelve dicho ancestro.

Expand Down
6 changes: 6 additions & 0 deletions 2-ui/3-event-details/7-keyboard-events/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,12 @@ In the past, there was a `keypress` event, and also `keyCode`, `charCode`, `whic

There were so many browser incompatibilities while working with them, that developers of the specification had no way, other than deprecating all of them and creating new, modern events (described above in this chapter). The old code still works, as browsers keep supporting them, but there's totally no need to use those any more.

## Mobile Keyboards

When using virtual/mobile keyboards, formally known as IME (Input-Method Editor), the W3C standard states that a KeyboardEvent's [`e.keyCode` should be `229`](https://www.w3.org/TR/uievents/#determine-keydown-keyup-keyCode) and [`e.key` should be `"Unidentified"`](https://www.w3.org/TR/uievents-key/#key-attr-values).

While some of these keyboards might still use the right values for `e.key`, `e.code`, `e.keyCode`... when pressing certain keys such as arrows or backspace, there's no guarantee, so your keyboard logic might not always work on mobile devices.

## Summary

Pressing a key always generates a keyboard event, be it symbol keys or special keys like `key:Shift` or `key:Ctrl` and so on. The only exception is `key:Fn` key that sometimes presents on a laptop keyboard. There's no keyboard event for it, because it's often implemented on lower level than OS.
Expand Down
44 changes: 44 additions & 0 deletions 5-network/04-fetch-abort/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,31 @@ Cuando `abort()` es invocado:
- `controller.signal` emite el evento `"abort"`.
- La propiedad `controller.signal.aborted` toma el valor `true`.

<<<<<<< HEAD
Generalmente tenemos dos partes en el proceso:
1. El que ejecuta la operación de cancelación, genera un listener que escucha a `controller.signal`.
2. El que cancela: este llama a `controller.abort()` cuendo es necesario.
=======
Generally, we have two parties in the process:
1. The one that performs a cancelable operation, it sets a listener on `controller.signal`.
2. The one that cancels: it calls `controller.abort()` when needed.
>>>>>>> 039716de8a96f49b5fccd7aed5effff2e719dfe5

Tal como se muestra a continuación (por ahora sin `fetch`):

```js run
let controller = new AbortController();
let signal = controller.signal;

<<<<<<< HEAD
// El que ejecuta la operación de cancelación
// obtiene el objeto "signal"
// y genera un listener que se dispara cuando es llamado controller.abort()
=======
// The party that performs a cancelable operation
// gets the "signal" object
// and sets the listener to trigger when controller.abort() is called
>>>>>>> 039716de8a96f49b5fccd7aed5effff2e719dfe5
signal.addEventListener('abort', () => alert("abort!"));

// El que cancela (más tarde en cualquier punto):
Expand All @@ -46,15 +58,27 @@ controller.abort(); // abort!
alert(signal.aborted); // true
```

<<<<<<< HEAD
Como podemos ver, `AbortController` es simplemente la via para pasar eventos `abort` cuando `abort()` es llamado sobre él.

Podríamos implementar alguna clase de escucha de evento en nuestro código por nuestra cuenta, sin el objeto `AbortController` en absoluto.

Pero lo valioso es que `fetch` sabe cómo trabajar con el objeto `AbortController`, está integrado con él.
=======
As we can see, `AbortController` is just a mean to pass `abort` events when `abort()` is called on it.

We could implement the same kind of event listening in our code on our own, without the `AbortController` object.

But what's valuable is that `fetch` knows how to work with the `AbortController` object. It's integrated in it.
>>>>>>> 039716de8a96f49b5fccd7aed5effff2e719dfe5

## Uso con fetch

<<<<<<< HEAD
Para posibilitar la cancelación de `fetch`, pasa la propiedad `signal` de un `AbortController` como una opción de `fetch`:
=======
To be able to cancel `fetch`, pass the `signal` property of an `AbortController` as a `fetch` option:
>>>>>>> 039716de8a96f49b5fccd7aed5effff2e719dfe5

```js
let controller = new AbortController();
Expand Down Expand Up @@ -97,7 +121,11 @@ try {

## AbortController es escalable

<<<<<<< HEAD
`AbortController` es escalable, permite cancelar múltiples fetch de una vez.
=======
`AbortController` is scalable. It allows to cancel multiple fetches at once.
>>>>>>> 039716de8a96f49b5fccd7aed5effff2e719dfe5

Aquí hay un bosquejo de código que de muchos fetch de `url` en paralelo, y usa un simple controlador para abortarlos a todos:

Expand All @@ -113,8 +141,13 @@ let fetchJobs = urls.map(url => fetch(url, {

let results = await Promise.all(fetchJobs);

<<<<<<< HEAD
// si controller.abort() es llamado,
// se abortaran todas las solicitudes fetch
=======
// if controller.abort() is called from anywhere,
// it aborts all fetches
>>>>>>> 039716de8a96f49b5fccd7aed5effff2e719dfe5
```

En el caso de tener nuestras propias tareas asincrónicas aparte de `fetch`, podemos utilizar un único `AbortController` para detenerlas junto con fetch.
Expand All @@ -137,12 +170,23 @@ let fetchJobs = urls.map(url => fetch(url, { // varios fetch
// Se espera por la finalización de los fetch y nuestra tarea
let results = await Promise.all([...fetchJobs, ourJob]);

<<<<<<< HEAD
// en caso de que se llame al método controller.abort() desde algún sitio,
// se abortan todos los fetch y nuestra tarea.
=======
// if controller.abort() is called from anywhere,
// it aborts all fetches and ourJob
>>>>>>> 039716de8a96f49b5fccd7aed5effff2e719dfe5
```

## Resumen

<<<<<<< HEAD
- `AbortController` es un simple objeto que genera un evento `abort` sobre su propiedad `signal` cuando el método `abort()` es llamado (y tambien establece `signal.aborted` en `true`).
- `fetch` está integrado con él: pasamos la propiedad `signal` como opción, y entonces `fetch` la escucha, así se vuelve posible abortar `fetch`.
- Podemos usar `AbortController` en nuestro código. La interacción "llamar `abort()`" -> "escuchar evento `abort`" es simple y universal. Podemos usarla incluso sin `fetch`.
=======
- `AbortController` is a simple object that generates an `abort` event on it's `signal` property when the `abort()` method is called (and also sets `signal.aborted` to `true`).
- `fetch` integrates with it: we pass the `signal` property as the option, and then `fetch` listens to it, so it's possible to abort the `fetch`.
- We can use `AbortController` in our code. The "call `abort()`" -> "listen to `abort` event" interaction is simple and universal. We can use it even without `fetch`.
>>>>>>> 039716de8a96f49b5fccd7aed5effff2e719dfe5
12 changes: 12 additions & 0 deletions 5-network/07-url/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,11 @@ Aquí está la hoja de trucos para los componentes URL:
```smart header="Podemos pasar objetos `URL` a métodos de red (y la mayoría de los demás) en lugar de un string"
Podemos usar un objeto `URL` en `fetch` o `XMLHttpRequest`, casi en todas partes donde se espera un URL-string.

<<<<<<< HEAD
Generalmente, un objeto `URL` puede pasarse a cualquier método en lugar de un string, ya que la mayoría de métodos llevarán a cabo la conversión del string, eso convierte un objeto `URL` en un string con URL completa.
=======
Generally, the `URL` object can be passed to any method instead of a string, as most methods will perform the string conversion, that turns a `URL` object into a string with full URL.
>>>>>>> 039716de8a96f49b5fccd7aed5effff2e719dfe5
```

## Parámetros de búsqueda "?..."
Expand All @@ -80,7 +84,11 @@ new URL('https://google.com/search?query=JavaScript')

...Pero los parámetros necesitan estar codificados si contienen espacios, letras no latinas, entre otros (Más sobre eso debajo).

<<<<<<< HEAD
Por lo que existe una propiedad URL para eso: `url.searchParams`, un objeto de tipo [URLSearchParams](https://url.spec.whatwg.org/#urlsearchparams).
=======
So there's a URL property for that: `url.searchParams`, an object of type [URLSearchParams](https://url.spec.whatwg.org/#urlsearchparams).
>>>>>>> 039716de8a96f49b5fccd7aed5effff2e719dfe5

Esta proporciona métodos convenientes para los parámetros de búsqueda:

Expand Down Expand Up @@ -201,7 +209,11 @@ Así que debemos usar solo `encodeURIComponent`para cada parámetro de búsqueda
````smart header="Diferencia de codificación comparado con `URL`"
Las clases [URL](https://url.spec.whatwg.org/#url-class) y [URLSearchParams](https://url.spec.whatwg.org/#interface-urlsearchparams) están basadas en la especificación URI mas reciente: [RFC3986](https://tools.ietf.org/html/rfc3986), mientras que las funciones `encode*` están basadas en la versión obsoleta [RFC2396](https://www.ietf.org/rfc/rfc2396.txt).

<<<<<<< HEAD
Existen algunas diferencias, por ej. las direcciones IPv6 se codifican de otra forma:
=======
There are a few differences, e.g. IPv6 addresses are encoded differently:
>>>>>>> 039716de8a96f49b5fccd7aed5effff2e719dfe5

```js run
// Url válida con dirección IPv6
Expand Down
8 changes: 8 additions & 0 deletions 9-regular-expressions/17-regexp-methods/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,21 @@ Divide la cadena usando la expresión regular (o una sub-cadena) como delimitado
Podemos usar `split` con cadenas, así:

```js run
<<<<<<< HEAD
alert('12-34-56'.split('-')) // array de [12, 34, 56]
=======
alert('12-34-56'.split('-')) // array of ['12', '34', '56']
>>>>>>> 039716de8a96f49b5fccd7aed5effff2e719dfe5
```

O también dividir una cadena usando una expresión regular de la misma forma:

```js run
<<<<<<< HEAD
alert('12, 34, 56'.split(/,\s*/)) // array de [12, 34, 56]
=======
alert('12, 34, 56'.split(/,\s*/)) // array of ['12', '34', '56']
>>>>>>> 039716de8a96f49b5fccd7aed5effff2e719dfe5
```

## str.search(regexp)
Expand Down