diff --git a/1-js/09-classes/02-class-inheritance/1-class-constructor-error/solution.md b/1-js/09-classes/02-class-inheritance/1-class-constructor-error/solution.md
index 4711e4827..16a66ec95 100644
--- a/1-js/09-classes/02-class-inheritance/1-class-constructor-error/solution.md
+++ b/1-js/09-classes/02-class-inheritance/1-class-constructor-error/solution.md
@@ -1,6 +1,6 @@
-That's because the child constructor must call `super()`.
+Eso es porque el constructor hijo debe llamar a `super()`.
-Here's the corrected code:
+Aqui está el código corregido:
```js run
class Animal {
@@ -21,7 +21,7 @@ class Rabbit extends Animal {
}
*!*
-let rabbit = new Rabbit("White Rabbit"); // ok now
+let rabbit = new Rabbit("Conejo Blanco"); // bueno ahora
*/!*
-alert(rabbit.name); // White Rabbit
+alert(rabbit.name); // Conejo Blanco
```
diff --git a/1-js/09-classes/02-class-inheritance/1-class-constructor-error/task.md b/1-js/09-classes/02-class-inheritance/1-class-constructor-error/task.md
index 380a4720b..cb582ac20 100644
--- a/1-js/09-classes/02-class-inheritance/1-class-constructor-error/task.md
+++ b/1-js/09-classes/02-class-inheritance/1-class-constructor-error/task.md
@@ -2,11 +2,11 @@ importance: 5
---
-# Error creating an instance
+# Error al crear una instancia
-Here's the code with `Rabbit` extending `Animal`.
+Aquí está el código de la clase `Rabbit` que extiende a`Animal`.
-Unfortunately, `Rabbit` objects can't be created. What's wrong? Fix it.
+Desafortunadamente, los objetos `Rabbit` no se pueden crear. ¿Que pasa? Arréglalo.
```js run
class Animal {
@@ -24,7 +24,7 @@ class Rabbit extends Animal {
}
*!*
-let rabbit = new Rabbit("White Rabbit"); // Error: this is not defined
+let rabbit = new Rabbit("Conejo Blanco"); // Error: esto no está definido
*/!*
alert(rabbit.name);
```
diff --git a/1-js/09-classes/02-class-inheritance/2-clock-class-extended/solution.view/extended-clock.js b/1-js/09-classes/02-class-inheritance/2-clock-class-extended/solution.view/extended-clock.js
index ca613ca5e..be2053cfc 100644
--- a/1-js/09-classes/02-class-inheritance/2-clock-class-extended/solution.view/extended-clock.js
+++ b/1-js/09-classes/02-class-inheritance/2-clock-class-extended/solution.view/extended-clock.js
@@ -1,7 +1,7 @@
class ExtendedClock extends Clock {
constructor(options) {
super(options);
- let { precision=1000 } = options;
+ let { precision = 1000 } = options;
this.precision = precision;
}
diff --git a/1-js/09-classes/02-class-inheritance/2-clock-class-extended/source.view/index.html b/1-js/09-classes/02-class-inheritance/2-clock-class-extended/source.view/index.html
index c0609858b..31c0df90f 100644
--- a/1-js/09-classes/02-class-inheritance/2-clock-class-extended/source.view/index.html
+++ b/1-js/09-classes/02-class-inheritance/2-clock-class-extended/source.view/index.html
@@ -7,7 +7,7 @@
clock.start();
- /* Your class should work like this: */
+ /* Tu clase debería funcionar así: */
/*
diff --git a/1-js/09-classes/02-class-inheritance/2-clock-class-extended/task.md b/1-js/09-classes/02-class-inheritance/2-clock-class-extended/task.md
index bbc2c6a43..2a49a45df 100644
--- a/1-js/09-classes/02-class-inheritance/2-clock-class-extended/task.md
+++ b/1-js/09-classes/02-class-inheritance/2-clock-class-extended/task.md
@@ -2,14 +2,14 @@ importance: 5
---
-# Extended clock
+# Reloj extendido
-We've got a `Clock` class. As of now, it prints the time every second.
+Tenemos una clase de 'Clock'. A partir de ahora, imprime la hora cada segundo.
[js src="source.view/clock.js"]
-Create a new class `ExtendedClock` that inherits from `Clock` and adds the parameter `precision` -- the number of `ms` between "ticks". Should be `1000` (1 second) by default.
+Crea una nueva clase `ExtendedClock` que herede de `Clock` y agrega el parámetro `precision`: este es el número de `milisegundos` entre "tics". Debe ser `1000` (1 segundo) por defecto.
-- Your code should be in the file `extended-clock.js`
-- Don't modify the original `clock.js`. Extend it.
+- Tu código debe estar en el archivo `extended-clock.js`
+- No modifiques el `clock.js` original. Extiéndelo.
diff --git a/1-js/09-classes/02-class-inheritance/3-class-extend-object/rabbit-extends-object.svg b/1-js/09-classes/02-class-inheritance/3-class-extend-object/rabbit-extends-object.svg
index 8ab568291..34d783b4d 100644
--- a/1-js/09-classes/02-class-inheritance/3-class-extend-object/rabbit-extends-object.svg
+++ b/1-js/09-classes/02-class-inheritance/3-class-extend-object/rabbit-extends-object.svg
@@ -1,67 +1 @@
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/09-classes/02-class-inheritance/3-class-extend-object/solution.md b/1-js/09-classes/02-class-inheritance/3-class-extend-object/solution.md
index fa26ec834..0f70aebc4 100644
--- a/1-js/09-classes/02-class-inheritance/3-class-extend-object/solution.md
+++ b/1-js/09-classes/02-class-inheritance/3-class-extend-object/solution.md
@@ -1,14 +1,14 @@
-First, let's see why the latter code doesn't work.
+Primero, veamos por qué el último código no funciona.
-The reason becomes obvious if we try to run it. An inheriting class constructor must call `super()`. Otherwise `"this"` won't be "defined".
+La razón se vuelve obvia si tratamos de ejecutarlo. Un constructor de clase heredado debe llamar a `super()`. De lo contrario, `"this"` no se "definirá".
-So here's the fix:
+Así que aquí está la solución:
```js run
class Rabbit extends Object {
constructor(name) {
*!*
- super(); // need to call the parent constructor when inheriting
+ super(); // necesita llamar al constructor padre al heredar
*/!*
this.name = name;
}
@@ -16,66 +16,66 @@ class Rabbit extends Object {
let rabbit = new Rabbit("Rab");
-alert( rabbit.hasOwnProperty('name') ); // true
+alert( rabbit.hasOwnProperty('name') ); // verdadero
```
-But that's not all yet.
+Pero eso no es todo aún.
-Even after the fix, there's still important difference in `"class Rabbit extends Object"` versus `class Rabbit`.
+Incluso después de la solución, todavía hay una diferencia importante en `"class Rabbit extends Objetc"` versus `class Rabbit`.
-As we know, the "extends" syntax sets up two prototypes:
+Como sabemos, la sintaxis "extends" configura dos prototipos:
-1. Between `"prototype"` of the constructor functions (for methods).
-2. Between the constructor functions itself (for static methods).
+1. Entre el `"prototype"` de las funcionalidades del constructor (para métodos).
+2. Entre las funcionalidades propias del constructor (para métodos estáticos).
-In our case, for `class Rabbit extends Object` it means:
+En nuestro caso, para `class Rabbit extends Object` significa::
```js run
class Rabbit extends Object {}
-alert( Rabbit.prototype.__proto__ === Object.prototype ); // (1) true
-alert( Rabbit.__proto__ === Object ); // (2) true
+alert( Rabbit.prototype.__proto__ === Object.prototype ); // (1) verdadero
+alert( Rabbit.__proto__ === Object ); // (2) verdadero
```
-So `Rabbit` now provides access to static methods of `Object` via `Rabbit`, like this:
+Entonces `Rabbit` ahora proporciona acceso a métodos estáticos de `Object` a través de `Rabbit`, como esto:
```js run
class Rabbit extends Object {}
*!*
-// normally we call Object.getOwnPropertyNames
+// normalmente llamamos Object.getOwnPropertyNames
alert ( Rabbit.getOwnPropertyNames({a: 1, b: 2})); // a,b
*/!*
```
-But if we don't have `extends Object`, then `Rabbit.__proto__` is not set to `Object`.
+Pero si no tenemos `extend Object', entonces `Rabbit.__ proto__` no está configurado como `Object`.
-Here's the demo:
+Aqui la demostración:
```js run
class Rabbit {}
-alert( Rabbit.prototype.__proto__ === Object.prototype ); // (1) true
-alert( Rabbit.__proto__ === Object ); // (2) false (!)
-alert( Rabbit.__proto__ === Function.prototype ); // as any function by default
+alert( Rabbit.prototype.__proto__ === Object.prototype ); // (1) verdadero
+alert( Rabbit.__proto__ === Object ); // (2) falso (!)
+alert( Rabbit.__proto__ === Function.prototype ); // como cualquier función por defecto
*!*
-// error, no such function in Rabbit
+// error, no hay tal función en Rabbit
alert ( Rabbit.getOwnPropertyNames({a: 1, b: 2})); // Error
*/!*
```
-So `Rabbit` doesn't provide access to static methods of `Object` in that case.
+Entonces `Rabbit` no proporciona acceso a métodos estáticos de 'Objeto' en ese caso.
-By the way, `Function.prototype` has "generic" function methods, like `call`, `bind` etc. They are ultimately available in both cases, because for the built-in `Object` constructor, `Object.__proto__ === Function.prototype`.
+Por cierto, `Function.prototype` tiene métodos de función "genéricos", como `call`, `bind` etc. En última instancia, están disponibles en ambos casos, porque para el constructor incorporado `Object`, `Object.__ proto__ === Function.prototype`.
-Here's the picture:
+Aqui está el gráfico:

-So, to put it short, there are two differences:
+Entonces, para resumir, hay dos diferencias:
| class Rabbit | class Rabbit extends Object |
|--------------|------------------------------|
-| -- | needs to call `super()` in constructor |
+| -- | necesita llamar a `super()` en el constructor |
| `Rabbit.__proto__ === Function.prototype` | `Rabbit.__proto__ === Object` |
diff --git a/1-js/09-classes/02-class-inheritance/3-class-extend-object/task.md b/1-js/09-classes/02-class-inheritance/3-class-extend-object/task.md
index ca6628edf..764aa9a84 100644
--- a/1-js/09-classes/02-class-inheritance/3-class-extend-object/task.md
+++ b/1-js/09-classes/02-class-inheritance/3-class-extend-object/task.md
@@ -1,12 +1,12 @@
-importance: 5
+importance: 3
---
-# Class extends Object?
+# Clase extiende objeto?
-As we know, all objects normally inherit from `Object.prototype` and get access to "generic" object methods like `hasOwnProperty` etc.
+Como sabemos, todos los objetos normalmente heredan de `Object.prototype` y obtienen acceso a métodos de objetos "genéricos" como `hasOwnProperty`, etc..
-For instance:
+Por ejemplo:
```js run
class Rabbit {
@@ -18,17 +18,16 @@ class Rabbit {
let rabbit = new Rabbit("Rab");
*!*
-// hasOwnProperty method is from Object.prototype
-// rabbit.__proto__ === Object.prototype
-alert( rabbit.hasOwnProperty('name') ); // true
+// el método hasOwnProperty es de Object.prototype
+alert( rabbit.hasOwnProperty('name') ); // verdadero
*/!*
```
-But if we spell it out explicitly like `"class Rabbit extends Object"`, then the result would be different from a simple `"class Rabbit"`?
+Pero si lo deletreamos explícitamente como `"clase Rabbit extends Objetc"`, entonces ¿el resultado sería diferente de un simple `"class Rabbit"`?
-What's the difference?
+¿Cual es la diferencia?
-Here's an example of such code (it doesn't work -- why? fix it?):
+Aquí hay un ejemplo de dicho código (no funciona, ¿por qué? ¿Solucionarlo?):
```js
class Rabbit extends Object {
@@ -39,5 +38,5 @@ class Rabbit extends Object {
let rabbit = new Rabbit("Rab");
-alert( rabbit.hasOwnProperty('name') ); // true
+alert( rabbit.hasOwnProperty('name') ); // Error
```
diff --git a/1-js/09-classes/02-class-inheritance/animal-rabbit-extends.svg b/1-js/09-classes/02-class-inheritance/animal-rabbit-extends.svg
index 7a55a5043..3471904ab 100644
--- a/1-js/09-classes/02-class-inheritance/animal-rabbit-extends.svg
+++ b/1-js/09-classes/02-class-inheritance/animal-rabbit-extends.svg
@@ -1,64 +1 @@
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/09-classes/02-class-inheritance/article.md b/1-js/09-classes/02-class-inheritance/article.md
index d6174b195..497a57e47 100644
--- a/1-js/09-classes/02-class-inheritance/article.md
+++ b/1-js/09-classes/02-class-inheritance/article.md
@@ -1,9 +1,13 @@
-# Class inheritance
+# Herencia de clase
-Let's say we have two classes.
+La herencia de clase es un método para que una clase extienda a otra clase.
-`Animal`:
+Entonces podemos crear una nueva funcionalidad además de la existente.
+
+## La palabra clave "extends"
+
+Digamos que tenemos la clase `Animal`:
```js
class Animal {
@@ -12,92 +16,62 @@ class Animal {
this.name = name;
}
run(speed) {
- this.speed += speed;
- alert(`${this.name} runs with speed ${this.speed}.`);
+ this.speed = speed;
+ alert(`${this.name} corre a una velocidad de ${this.speed}.`);
}
stop() {
this.speed = 0;
- alert(`${this.name} stopped.`);
+ alert(`${this.name} se queda quieto.`);
}
}
-let animal = new Animal("My animal");
+let animal = new Animal("Mi animal");
```
-
-
-
-...And `Rabbit`:
+Así es como podemos representar gráficamente el objeto `animal` y la clase `Animal`:
-```js
-class Rabbit extends Animal {
- constructor(name) {
- this.name = name;
- }
- hide() {
- alert(`${this.name} hides!`);
- }
-}
-
-let rabbit = new Rabbit("My rabbit");
-```
-
-
-
-
-Right now they are fully independent.
+
-But we'd want `Rabbit` to extend `Animal`. In other words, rabbits should be based on animals, have access to methods of `Animal` and extend them with its own methods.
+...Y nos gustaría crear otra clase `Rabbit`.
-To inherit from another class, we should specify `"extends"` and the parent class before the brackets `{..}`.
+Como los conejos son animales, la clase 'Rabbit' debe basarse en 'Animal', tener acceso a métodos animales, para que los conejos puedan hacer lo que los animales "genéricos" pueden hacer.
-Here `Rabbit` inherits from `Animal`:
+La sintaxis para extender otra clase es: `class Child extends Parent`.
-```js run
-class Animal {
- constructor(name) {
- this.speed = 0;
- this.name = name;
- }
- run(speed) {
- this.speed += speed;
- alert(`${this.name} runs with speed ${this.speed}.`);
- }
- stop() {
- this.speed = 0;
- alert(`${this.name} stopped.`);
- }
-}
+Construyamos la clase `Rabbit` que herede de `Animal`:
+```js
*!*
-// Inherit from Animal
class Rabbit extends Animal {
+*/!*
hide() {
- alert(`${this.name} hides!`);
+ alert(`${this.name} se esconde!`);
}
}
-*/!*
-let rabbit = new Rabbit("White Rabbit");
+let rabbit = new Rabbit("Conejo Blanco");
-rabbit.run(5); // White Rabbit runs with speed 5.
-rabbit.hide(); // White Rabbit hides!
+rabbit.run(5); // Conejo Blanco corre a una velocidad de 5.
+rabbit.hide(); // Conejo Blanco se esconde!
```
-Now the `Rabbit` code became a bit shorter, as it uses `Animal` constructor by default, and it also can `run`, as animals do.
+Los objetos de la clase `Rabbit` tienen acceso a los métodos de `Rabbit`, como `rabbit.hide()`, y también a los métodos `Animal`, como `rabbit.run()`.
-Internally, `extends` keyword adds `[[Prototype]]` reference from `Rabbit.prototype` to `Animal.prototype`:
+Internamente, la palabra clave `extends` funciona con la buena mecánica de prototipo. Establece `Rabbit.prototype. [[Prototype]]` a `Animal.prototype`. Entonces, si no se encuentra un método en `Rabbit.prototype`, JavaScript lo toma de` Animal.prototype`.

-So, if a method is not found in `Rabbit.prototype`, JavaScript takes it from `Animal.prototype`.
+Por ejemplo, para encontrar el método `rabbit.run`, el motor verifica (de abajo hacia arriba en la imagen) que:
+1. El objeto `rabbit` (no tiene el método `run`).
+2. Su prototipo, que es `Rabbit.prototype` (tiene el método `hide`, pero no el método `run`).
+3. Su prototipo, es decir (debido a `extends`) `Animal.prototype`, este finalmente tiene el método `run`.
-As we can recall from the chapter , JavaScript uses the same prototypal inheritance for build-in objects. E.g. `Date.prototype.[[Prototype]]` is `Object.prototype`, so dates have generic object methods.
+Como podemos recordar del capítulo , JavaScript usa la misma herencia prototípica para los objetos incorporados. P.ej. `Date.prototype.[[Prototype]]` es `Object.prototype`, por lo que "Date" tiene métodos de objeto genéricos.
-````smart header="Any expression is allowed after `extends`"
-Class syntax allows to specify not just a class, but any expression after `extends`.
+````smart header="Cualquier expresión está permitida después de `extends`"
+La sintaxis de clase permite especificar no solo una clase, sino cualquier expresión después de `extends`.
-For instance, a function call that generates the parent class:
+Por ejemplo, una llamada a función que genera la clase padre:
```js run
function f(phrase) {
@@ -107,39 +81,39 @@ function f(phrase) {
}
*!*
-class User extends f("Hello") {}
+class User extends f("Hola") {}
*/!*
-new User().sayHi(); // Hello
+new User().sayHi(); // Hola
```
-Here `class User` inherits from the result of `f("Hello")`.
+Aquí `class User` hereda del resultado de `f("Hola")`.
-That may be useful for advanced programming patterns when we use functions to generate classes depending on many conditions and can inherit from them.
+Eso puede ser útil para patrones de programación avanzados cuando usamos funciones para generar clases dependiendo de muchas condiciones y podamos heredar de ellas.
````
-## Overriding a method
+## Anular un método
-Now let's move forward and override a method. As of now, `Rabbit` inherits the `stop` method that sets `this.speed = 0` from `Animal`.
+Ahora avancemos y anulemos un método. Por defecto, todos los métodos que no están especificados en la clase `Rabbit` se toman directamente "tal cual" de la clase `Animal`.
-If we specify our own `stop` in `Rabbit`, then it will be used instead:
+Si especificamos nuestro propio método `stop()` en `Rabbit`, se utilizará en su lugar:
```js
class Rabbit extends Animal {
stop() {
- // ...this will be used for rabbit.stop()
+ // ...esto se usará para rabbit.stop()
+ // en lugar de stop () de la clase Animal
}
}
```
+...Pero, por lo general, no queremos reemplazar totalmente un método padre, sino más bien construir sobre él, modificar o ampliar su funcionalidad. Hacemos algo en nuestro método, pero llamamos al método padre antes/después o en el proceso.
-...But usually we don't want to totally replace a parent method, but rather to build on top of it, tweak or extend its functionality. We do something in our method, but call the parent method before/after it or in the process.
+Las clases proporcionan la palabra clave `"super"` para eso.
-Classes provide `"super"` keyword for that.
+- `super.method(...)` llamar a un método padre.
+- `super(...)` llamar a un constructor padre (solo dentro de nuestro constructor).
-- `super.method(...)` to call a parent method.
-- `super(...)` to call a parent constructor (inside our constructor only).
-
-For instance, let our rabbit autohide when stopped:
+Por ejemplo, dejemos que nuestro conejo se oculte automáticamente cuando se detenga:
```js run
class Animal {
@@ -150,70 +124,70 @@ class Animal {
}
run(speed) {
- this.speed += speed;
- alert(`${this.name} runs with speed ${this.speed}.`);
+ this.speed = speed;
+ alert(`${this.name} corre a una velocidad de ${this.speed}.`);
}
stop() {
this.speed = 0;
- alert(`${this.name} stopped.`);
+ alert(`${this.name} se queda quieto.`);
}
}
class Rabbit extends Animal {
hide() {
- alert(`${this.name} hides!`);
+ alert(`${this.name} se esconde!`);
}
*!*
stop() {
- super.stop(); // call parent stop
- this.hide(); // and then hide
+ super.stop(); // llama el stop padre
+ this.hide(); // y luego hide
}
*/!*
}
-let rabbit = new Rabbit("White Rabbit");
+let rabbit = new Rabbit("Conejo Blanco");
-rabbit.run(5); // White Rabbit runs with speed 5.
-rabbit.stop(); // White Rabbit stopped. White rabbit hides!
+rabbit.run(5); // Conejo Blanco corre a una velocidad de 5.
+rabbit.stop(); // Conejo Blanco se queda quieto. Conejo Blanco se esconde!
```
-Now `Rabbit` has the `stop` method that calls the parent `super.stop()` in the process.
+Ahora `Rabbit` tiene el método `stop` que llama al padre `super.stop()` en el proceso.
-````smart header="Arrow functions have no `super`"
-As was mentioned in the chapter , arrow functions do not have `super`.
+````smart header="Las funciones de flecha no tienen `super`"
+Como se mencionó en el capítulo , las funciones de flecha no tienen `super`.
-If accessed, it's taken from the outer function. For instance:
+Si se accede, se toma de la función externa. Por ejemplo:
```js
class Rabbit extends Animal {
stop() {
- setTimeout(() => super.stop(), 1000); // call parent stop after 1sec
+ setTimeout(() => super.stop(), 1000); // llama al padre stop despues de 1seg
}
}
```
-The `super` in the arrow function is the same as in `stop()`, so it works as intended. If we specified a "regular" function here, there would be an error:
+El método `super` en la función de flecha es el mismo que en `stop()`, por lo que funciona según lo previsto. Si especificamos una función "regular" aquí, habría un error:
```js
-// Unexpected super
+// super inesperado
setTimeout(function() { super.stop() }, 1000);
```
````
-## Overriding constructor
+## Anular un constructor
-With constructors it gets a little bit tricky.
+Con los constructores se pone un poco complicado.
-Till now, `Rabbit` did not have its own `constructor`.
+Hasta ahora, `Rabbit` no tenía su propio `constructor`.
-According to the [specification](https://tc39.github.io/ecma262/#sec-runtime-semantics-classdefinitionevaluation), if a class extends another class and has no `constructor`, then the following `constructor` is generated:
+De acuerdo con la [especificación] (https://tc39.github.io/ecma262/#sec-runtime-semantics-classdefinitionevaluation), si una clase extiende otra clase y no tiene `constructor`, se genera el siguiente `constructor` "vacío":
```js
class Rabbit extends Animal {
- // generated for extending classes without own constructors
+ // generado para extender clases sin constructores propios
*!*
constructor(...args) {
super(...args);
@@ -222,9 +196,9 @@ class Rabbit extends Animal {
}
```
-As we can see, it basically calls the parent `constructor` passing it all the arguments. That happens if we don't write a constructor of our own.
+Como podemos ver, básicamente llama al padre `constructor` pasándole todos los argumentos. Eso sucede si no escribimos un constructor propio.
-Now let's add a custom constructor to `Rabbit`. It will specify the `earLength` in addition to `name`:
+Ahora agreguemos un constructor personalizado a `Rabbit`. Especificará `earLength` además de `name`:
```js run
class Animal {
@@ -249,29 +223,29 @@ class Rabbit extends Animal {
}
*!*
-// Doesn't work!
-let rabbit = new Rabbit("White Rabbit", 10); // Error: this is not defined.
+// No funciona!
+let rabbit = new Rabbit("Conejo Blanco", 10); // Error: esto no está definido.
*/!*
```
-Whoops! We've got an error. Now we can't create rabbits. What went wrong?
+Whoops! Tenemos un error. Ahora no podemos crear conejos. ¿Qué salió mal?
-The short answer is: constructors in inheriting classes must call `super(...)`, and (!) do it before using `this`.
+La respuesta corta es: los constructores en las clases heredadas deben llamar a `super(...)`, y (!) Hacerlo antes de usar `this`.
-...But why? What's going on here? Indeed, the requirement seems strange.
+...¿Pero por qué? ¿Que está pasando aqui? De hecho, el requisito parece extraño.
-Of course, there's an explanation. Let's get into details, so you'd really understand what's going on.
+Por supuesto, hay una explicación. Vamos a entrar en detalles, para que realmente entiendas lo que está pasando.
-In JavaScript, there's a distinction between a "constructor function of an inheriting class" and all others. In an inheriting class, the corresponding constructor function is labelled with a special internal property `[[ConstructorKind]]:"derived"`.
+En JavaScript, hay una distinción entre una función constructora de una clase heredera (llamada "constructor derivado") y otras funciones. Un constructor derivado tiene una propiedad interna especial `[[ConstructorKind]]:"derived"`. Esa es una etiqueta interna especial.
-The difference is:
+Esa etiqueta afecta su comportamiento con `new`.
-- When a normal constructor runs, it creates an empty object as `this` and continues with it.
-- But when a derived constructor runs, it doesn't do it. It expects the parent constructor to do this job.
+- Cuando una función regular se ejecuta con `new`, crea un objeto vacío y lo asigna a `this`.
+- Pero cuando se ejecuta un constructor derivado, no hace esto. Espera que el constructor padre haga este trabajo.
-So if we're making a constructor of our own, then we must call `super`, because otherwise the object with `this` reference to it won't be created. And we'll get an error.
+Por lo tanto, un constructor derivado debe llamar a `super` para ejecutar su constructor padre (no derivado), de lo contrario no se creará el objeto para `this`. Y obtendremos un error.
-For `Rabbit` to work, we need to call `super()` before using `this`, like here:
+Para que el constructor `Rabbit` funcione, necesita llamar a `super()` antes de usar `this`, como aquí:
```js run
class Animal {
@@ -298,32 +272,40 @@ class Rabbit extends Animal {
*!*
// now fine
-let rabbit = new Rabbit("White Rabbit", 10);
-alert(rabbit.name); // White Rabbit
+let rabbit = new Rabbit("Conejo Blanco", 10);
+alert(rabbit.name); // Conejo Blanco
alert(rabbit.earLength); // 10
*/!*
```
-## Super: internals, [[HomeObject]]
+## [[HomeObject]]: el `super` interno
+
+```warn header="Información avanzada"
+Si está leyendo el tutorial por primera vez, esta sección puede omitirse.
+
+Esta sección trata de los mecanismos internos detrás de la herencia y el método `super`.
+```
-Let's get a little deeper under the hood of `super`. We'll see some interesting things by the way.
+Vamos a profundizar un poco más bajo la sombra de `super`. Veremos algunas cosas interesantes en el camino.
-First to say, from all that we've learned till now, it's impossible for `super` to work.
+En primer lugar, de todo lo que hemos aprendido hasta ahora, ¡es imposible que `super` funcione en absoluto!
-Yeah, indeed, let's ask ourselves, how it could technically work? When an object method runs, it gets the current object as `this`. If we call `super.method()` then, how to retrieve the `method`? Naturally, we need to take the `method` from the prototype of the current object. How, technically, we (or a JavaScript engine) can do it?
+Sí, de hecho, preguntémonos, ¿cómo debería funcionar técnicamente? Cuando se ejecuta un método de objeto, obtiene el objeto actual como `this`. Si llamamos a `super.method()` entonces, el motor necesita obtener el `method` del prototipo del objeto actual. ¿Pero cómo?
-Maybe we can get the method from `[[Prototype]]` of `this`, as `this.__proto__.method`? Unfortunately, that doesn't work.
+La tarea puede parecer simple, pero no lo es. El motor conoce el objeto actual `this`, por lo que podría obtener el `method` padre como `this.__proto __.method`. Desafortunadamente, una solución tan "ingenua" no funcionará.
-Let's try to do it. Without classes, using plain objects for the sake of simplicity.
+Demostremos el problema. Sin clases, usando objetos simples en aras de la simplicidad.
-Here, `rabbit.eat()` should call `animal.eat()` method of the parent object:
+Puedes omitir esta parte e ir a la subsección `[[HomeObject]]` si no deseas conocer los detalles. Eso no hará daño. O sigue leyendo si estás interesado en comprender las cosas en profundidad.
+
+En el siguiente ejemplo, `rabbit.__ proto__ = animal`. Ahora intentemos: en `rabbit.eat()` llamaremos a `animal.eat()`, usando `this.__ proto__`:
```js run
let animal = {
name: "Animal",
eat() {
- alert(`${this.name} eats.`);
+ alert(`${this.name} come.`);
}
};
@@ -332,33 +314,33 @@ let rabbit = {
name: "Rabbit",
eat() {
*!*
- // that's how super.eat() could presumably work
+ // así es como supuestamente podría funcionar super.eat()
this.__proto__.eat.call(this); // (*)
*/!*
}
};
-rabbit.eat(); // Rabbit eats.
+rabbit.eat(); // Rabbit come.
```
-At the line `(*)` we take `eat` from the prototype (`animal`) and call it in the context of the current object. Please note that `.call(this)` is important here, because a simple `this.__proto__.eat()` would execute parent `eat` in the context of the prototype, not the current object.
+En la línea `(*)` tomamos `eat` del prototipo (`animal`) y lo llamamos en el contexto del objeto actual. Tenga en cuenta que `.call(this)` es importante aquí, porque un simple `this.__ proto __.eat()` ejecutaría al padre `eat` en el contexto del prototipo, no del objeto actual.
-And in the code above it actually works as intended: we have the correct `alert`.
+Y en el código anterior, en realidad funciona según lo previsto: tenemos el `alert` correcto.
-Now let's add one more object to the chain. We'll see how things break:
+Ahora agreguemos un objeto más a la cadena. Veremos cómo se rompen las cosas:
```js run
let animal = {
name: "Animal",
eat() {
- alert(`${this.name} eats.`);
+ alert(`${this.name} come.`);
}
};
let rabbit = {
__proto__: animal,
eat() {
- // ...bounce around rabbit-style and call parent (animal) method
+ // ...rebota alrededor al estilo de conejo y llama al método padre (animal)
this.__proto__.eat.call(this); // (*)
}
};
@@ -366,100 +348,158 @@ let rabbit = {
let longEar = {
__proto__: rabbit,
eat() {
- // ...do something with long ears and call parent (rabbit) method
+ // ...haz algo con orejas largas y llama al método padre (rabbit)
this.__proto__.eat.call(this); // (**)
}
};
*!*
-longEar.eat(); // Error: Maximum call stack size exceeded
+longEar.eat(); // Error: Se excedió el número máximo de llamadas a la pila
*/!*
```
-The code doesn't work anymore! We can see the error trying to call `longEar.eat()`.
+¡El código ya no funciona! Podemos ver el error al intentar llamar a `longEar.eat()`.
-It may be not that obvious, but if we trace `longEar.eat()` call, then we can see why. In both lines `(*)` and `(**)` the value of `this` is the current object (`longEar`). That's essential: all object methods get the current object as `this`, not a prototype or something.
+Puede que no sea tan obvio, pero si rastreamos la llamada `longEar.eat()`, entonces podemos ver por qué. En ambas líneas `(*)` y `(**)` el valor de `this` es el objeto actual (`longEar`). Eso es esencial: todos los métodos de objeto obtienen el objeto actual como `this`, no un prototipo o algo así.
-So, in both lines `(*)` and `(**)` the value of `this.__proto__` is exactly the same: `rabbit`. They both call `rabbit.eat` without going up the chain in the endless loop.
+Entonces, en ambas líneas `(*)` y `(**)` el valor de `this.__ proto__` es exactamente el mismo: `rabbit`. Ambos llaman a `rabbit.eat` sin subir la cadena en el bucle sin fin.
-Here's the picture of what happens:
+Aquí está la imagen de lo que sucede:

-1. Inside `longEar.eat()`, the line `(**)` calls `rabbit.eat` providing it with `this=longEar`.
+1. Dentro de `longEar.eat()`, la línea `(**)` llama a `rabbit.eat` proporcionándole `this=longEar`.
```js
- // inside longEar.eat() we have this = longEar
+ // dentro de longEar.eat() tenemos this = longEar
this.__proto__.eat.call(this) // (**)
- // becomes
+ // se convierte en
longEar.__proto__.eat.call(this)
- // that is
+ // es decir
rabbit.eat.call(this);
```
-2. Then in the line `(*)` of `rabbit.eat`, we'd like to pass the call even higher in the chain, but `this=longEar`, so `this.__proto__.eat` is again `rabbit.eat`!
+2. Luego, en la línea `(*)` de `rabbit.eat`, nos gustaría pasar la llamada aún más arriba en la cadena, pero `this=longEar`, entonces `this.__ proto __.eat` es nuevamente `rabbit.eat`!
```js
- // inside rabbit.eat() we also have this = longEar
+ // dentro de rabbit.eat () también tenemos this = longEar
this.__proto__.eat.call(this) // (*)
- // becomes
+ // se convierte en
longEar.__proto__.eat.call(this)
- // or (again)
+ // o (de nuevo)
rabbit.eat.call(this);
```
-3. ...So `rabbit.eat` calls itself in the endless loop, because it can't ascend any further.
+3. ...Entonces `rabbit.eat` se llama a sí mismo en el bucle sin fin, porque no puede ascender más.
-The problem can't be solved by using `this` alone.
+El problema no se puede resolver usando solo `this`.
### `[[HomeObject]]`
-To provide the solution, JavaScript adds one more special internal property for functions: `[[HomeObject]]`.
-
-**When a function is specified as a class or object method, its `[[HomeObject]]` property becomes that object.**
+Para proporcionar la solución, JavaScript agrega una propiedad interna especial más para las funciones: `[[HomeObject]]`.
-This actually violates the idea of "unbound" functions, because methods remember their objects. And `[[HomeObject]]` can't be changed, so this bound is forever. So that's a very important change in the language.
+Cuando una función se especifica como un método de clase u objeto, su propiedad `[[HomeObject]]` se convierte en ese objeto.
-But this change is safe. `[[HomeObject]]` is used only for calling parent methods in `super`, to resolve the prototype. So it doesn't break compatibility.
+Entonces `super` lo usa para resolver el problema del prototipo padre y sus métodos.
-Let's see how it works for `super` -- again, using plain objects:
+Veamos cómo funciona, primero con objetos simples:
```js run
let animal = {
name: "Animal",
- eat() { // [[HomeObject]] == animal
- alert(`${this.name} eats.`);
+ eat() { // animal.eat.[[HomeObject]] == animal
+ alert(`${this.name} come.`);
}
};
let rabbit = {
__proto__: animal,
name: "Rabbit",
- eat() { // [[HomeObject]] == rabbit
+ eat() { // rabbit.eat.[[HomeObject]] == rabbit
super.eat();
}
};
let longEar = {
__proto__: rabbit,
- name: "Long Ear",
- eat() { // [[HomeObject]] == longEar
+ name: "Oreja Larga",
+ eat() { // longEar.eat.[[HomeObject]] == longEar
super.eat();
}
};
*!*
-longEar.eat(); // Long Ear eats.
+// funciona correctamente
+longEar.eat(); // Oreja Larga come.
*/!*
```
-Every method remembers its object in the internal `[[HomeObject]]` property. Then `super` uses it to resolve the parent prototype.
+Funciona según lo previsto, debido a la mecánica de `[[HomeObject]]`. Un método, como `longEar.eat`, conoce su `[[HomeObject]]` y toma el método padre de su prototipo. Sin el uso de `this`.
+
+### Los métodos no son "libres"
+
+Como hemos sabido antes, generalmente las funciones son "libres", no vinculadas a objetos en JavaScript. Para que puedan copiarse entre objetos y llamarse con otro 'this`.
+
+La existencia misma de `[[HomeObject]]` viola ese principio, porque los métodos recuerdan sus objetos. `[[HomeObject]]` no se puede cambiar, por lo que este vínculo es para siempre.
-`[[HomeObject]]` is defined for methods defined both in classes and in plain objects. But for objects, methods must be specified exactly the given way: as `method()`, not as `"method: function()"`.
+El único lugar en el lenguaje donde se usa `[[HomeObject]]` es en `super`. Si un método no usa `super`, entonces todavía podemos considerarlo "libre" y copiarlo entre objetos. Pero con `super` las cosas pueden salir mal.
-In the example below a non-method syntax is used for comparison. `[[HomeObject]]` property is not set and the inheritance doesn't work:
+Aquí está la demostración de un resultado `super` incorrecto después de copiar:
```js run
let animal = {
- eat: function() { // should be the short syntax: eat() {...}
+ sayHi() {
+ console.log(`Soy un animal`);
+ }
+};
+
+// conejo hereda de animal
+let rabbit = {
+ __proto__: animal,
+ sayHi() {
+ super.sayHi();
+ }
+};
+
+let plant = {
+ sayHi() {
+ console.log("Soy una planta");
+ }
+};
+
+// arbol hereda de planta
+let tree = {
+ __proto__: plant,
+*!*
+ sayHi: rabbit.sayHi // (*)
+*/!*
+};
+
+*!*
+tree.sayHi(); // Soy un animal (?!?)
+*/!*
+```
+
+Una llamada a `tree.sayHi()` muestra "Soy un animal". Definitivamente mal.
+
+La razón es simple:
+- En la línea `(*)`, el método `tree.sayHi` se copió de `rabbit`. ¿Quizás solo queríamos evitar la duplicación de código?
+- Su `[[HomeObject]]` es `rabbit`, ya que fue creado en `rabbit`. No hay forma de cambiar `[[HomeObject]]`.
+- El código de `tree.sayHi()` tiene dentro a `super.sayHi()`. Sube de 'rabbit' y toma el método de 'animal'.
+
+Aquí está el diagrama de lo que sucede:
+
+
+
+### Métodos, no propiedades de función
+
+`[[HomeObject]]` se define para métodos tanto en clases como en objetos simples. Pero para los objetos, los métodos deben especificarse exactamente como `method()`, no como `"method: function()"`.
+
+La diferencia puede no ser esencial para nosotros, pero es importante para JavaScript.
+
+En el siguiente ejemplo, se utiliza una sintaxis que no es de método para la comparación. La propiedad `[[HomeObject]]` no está establecida y la herencia no funciona:
+
+```js run
+let animal = {
+ eat: function() { // escribiendo intencionalmente así en lugar de eat() {...
// ...
}
};
@@ -472,6 +512,21 @@ let rabbit = {
};
*!*
-rabbit.eat(); // Error calling super (because there's no [[HomeObject]])
+rabbit.eat(); // Error al llamar a super (porque no hay [[HomeObject]])
*/!*
```
+
+## Resumen
+
+1. Para extender una clase: `class Child extends Parent`:
+ - Eso significa que `Child.prototype.__proto__` será `Parent.prototype`, por lo que los métodos se heredan.
+2. Al anular un constructor:
+ - Debemos llamar al constructor padre como `super()` en el constructor `Child` antes de usar `this`.
+3. Al anular otro método:
+ - Podemos usar `super.method()` en un método `Child` para llamar al método `Parent`.
+4. Partes internas:
+ - Los métodos recuerdan su clase/objeto en la propiedad interna `[[HomeObject]]`. Así es como `super` resuelve los métodos padres.
+ - Por lo tanto, no es seguro copiar un método con `super` de un objeto a otro.
+
+También:
+- Las funciones de flecha no tienen su propio `this` o` super`, por lo que se ajustan de manera transparente al contexto circundante.
diff --git a/1-js/09-classes/02-class-inheritance/class-inheritance-array-object.svg b/1-js/09-classes/02-class-inheritance/class-inheritance-array-object.svg
index 6f2124ebb..10af6c4c2 100644
--- a/1-js/09-classes/02-class-inheritance/class-inheritance-array-object.svg
+++ b/1-js/09-classes/02-class-inheritance/class-inheritance-array-object.svg
@@ -1,41 +1 @@
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/09-classes/02-class-inheritance/class-inheritance-rabbit-animal-2.svg b/1-js/09-classes/02-class-inheritance/class-inheritance-rabbit-animal-2.svg
index 9714d6708..a81676e25 100644
--- a/1-js/09-classes/02-class-inheritance/class-inheritance-rabbit-animal-2.svg
+++ b/1-js/09-classes/02-class-inheritance/class-inheritance-rabbit-animal-2.svg
@@ -1,62 +1 @@
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/09-classes/02-class-inheritance/class-inheritance-rabbit-animal.svg b/1-js/09-classes/02-class-inheritance/class-inheritance-rabbit-animal.svg
index 249bfa4c9..35529aa43 100644
--- a/1-js/09-classes/02-class-inheritance/class-inheritance-rabbit-animal.svg
+++ b/1-js/09-classes/02-class-inheritance/class-inheritance-rabbit-animal.svg
@@ -1,39 +1 @@
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/09-classes/02-class-inheritance/rabbit-animal-independent-animal.svg b/1-js/09-classes/02-class-inheritance/rabbit-animal-independent-animal.svg
index 7a16b7855..905efe37a 100644
--- a/1-js/09-classes/02-class-inheritance/rabbit-animal-independent-animal.svg
+++ b/1-js/09-classes/02-class-inheritance/rabbit-animal-independent-animal.svg
@@ -1,42 +1 @@
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/09-classes/02-class-inheritance/rabbit-animal-independent-rabbit.svg b/1-js/09-classes/02-class-inheritance/rabbit-animal-independent-rabbit.svg
index ab936c151..81bf1850b 100644
--- a/1-js/09-classes/02-class-inheritance/rabbit-animal-independent-rabbit.svg
+++ b/1-js/09-classes/02-class-inheritance/rabbit-animal-independent-rabbit.svg
@@ -1,41 +1 @@
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/09-classes/02-class-inheritance/super-homeobject-wrong.svg b/1-js/09-classes/02-class-inheritance/super-homeobject-wrong.svg
new file mode 100644
index 000000000..f13d441c9
--- /dev/null
+++ b/1-js/09-classes/02-class-inheritance/super-homeobject-wrong.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/1-js/09-classes/02-class-inheritance/this-super-loop.svg b/1-js/09-classes/02-class-inheritance/this-super-loop.svg
index 7862b41c0..bc200fab3 100644
--- a/1-js/09-classes/02-class-inheritance/this-super-loop.svg
+++ b/1-js/09-classes/02-class-inheritance/this-super-loop.svg
@@ -1,72 +1 @@
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/1-js/09-classes/05-extend-natives/article.md b/1-js/09-classes/05-extend-natives/article.md
index 4cf1c2bdd..c2195c510 100644
--- a/1-js/09-classes/05-extend-natives/article.md
+++ b/1-js/09-classes/05-extend-natives/article.md
@@ -1,12 +1,12 @@
-# Extending built-in classes
+# Ampliación de clases integradas
-Built-in classes like Array, Map and others are extendable also.
+Las clases integradas como Array, Map y otras también son extensibles.
-For instance, here `PowerArray` inherits from the native `Array`:
+Por ejemplo, aquí `PowerArray` hereda del nativo `Array`:
```js run
-// add one more method to it (can do more)
+// se agrega un método más (puedes hacer más)
class PowerArray extends Array {
isEmpty() {
return this.length === 0;
@@ -14,28 +14,27 @@ class PowerArray extends Array {
}
let arr = new PowerArray(1, 2, 5, 10, 50);
-alert(arr.isEmpty()); // false
+alert(arr.isEmpty()); // falso
let filteredArr = arr.filter(item => item >= 10);
alert(filteredArr); // 10, 50
-alert(filteredArr.isEmpty()); // false
+alert(filteredArr.isEmpty()); // falso
```
-Please note a very interesting thing. Built-in methods like `filter`, `map` and others -- return new objects of exactly the inherited type. They rely on the `constructor` property to do so.
+Tenga en cuenta una cosa muy interesante. Métodos incorporados como `filter`, `map` y otros: devuelven nuevos objetos exactamente del tipo heredado `PowerArray`. Su implementación interna utiliza la propiedad `constructor` del objeto para eso.
-In the example above,
+En el ejemplo anterior,
```js
arr.constructor === PowerArray
```
-So when `arr.filter()` is called, it internally creates the new array of results exactly as `new PowerArray`.
-That's actually very cool, because we can keep using `PowerArray` methods further on the result.
+Cuando se llama a `arr.filter()`, crea internamente la nueva matriz de resultados usando exactamente `arr.constructor`, no el básico `Array`. En realidad, eso es muy bueno, porque podemos seguir usando métodos `PowerArray` más adelante en el resultado.
-Even more, we can customize that behavior.
+Aún más, podemos personalizar ese comportamiento.
-There's a special static getter `Symbol.species`, if exists, it returns the constructor to use in such cases.
+Podemos agregar un `getter` estático especial `Symbol.species` a la clase. Si existe, debería devolver el constructor que JavaScript usará internamente para crear nuevas entidades en `map`, `filter` y así sucesivamente.
-If we'd like built-in methods like `map`, `filter` will return regular arrays, we can return `Array` in `Symbol.species`, like here:
+Si queremos que los métodos incorporados como `map` o `filter` devuelvan matrices regulares, podemos devolver `Array` en `Symbol.species`, como aquí:
```js run
class PowerArray extends Array {
@@ -44,7 +43,7 @@ class PowerArray extends Array {
}
*!*
- // built-in methods will use this as the constructor
+ // los métodos incorporados usarán esto como el constructor
static get [Symbol.species]() {
return Array;
}
@@ -52,31 +51,39 @@ class PowerArray extends Array {
}
let arr = new PowerArray(1, 2, 5, 10, 50);
-alert(arr.isEmpty()); // false
+alert(arr.isEmpty()); // falso
-// filter creates new array using arr.constructor[Symbol.species] as constructor
+// filter crea una nueva matriz usando arr.constructor[Symbol.species] como constructor
let filteredArr = arr.filter(item => item >= 10);
*!*
-// filteredArr is not PowerArray, but Array
+// filterArr no es PowerArray, sino Array
*/!*
-alert(filteredArr.isEmpty()); // Error: filteredArr.isEmpty is not a function
+alert(filteredArr.isEmpty()); // Error: filterArr.isEmpty no es una función
```
-As you can see, now `.filter` returns `Array`. So the extended functionality is not passed any further.
+Como puede ver, ahora `.filter` devuelve `Array`. Por lo tanto, la funcionalidad extendida ya no se pasa.
-## No static inheritance in built-ins
+```smart header="Other collections trabaja similarmente"
+Otras colecciones, como `Map` y `Set`, funcionan igual. También usan `Symbol.species`.
+```
+
+## Sin herencia estática en incorporados
-Built-in objects have their own static methods, for instance `Object.keys`, `Array.isArray` etc.
+Los objetos incorporados tienen sus propios métodos estáticos, por ejemplo, `Object.keys`, `Array.isArray`, etc.
-And we've already been talking about native classes extending each other: `Array.[[Prototype]] = Object`.
+Como ya sabemos, las clases nativas se extienden entre sí. Por ejemplo, `Array` extiende `Object`.
-But statics are an exception. Built-in classes don't inherit static properties from each other.
+Normalmente, cuando una clase extiende a otra, se heredan los métodos estáticos y no estáticos. Eso se explicó a fondo en el artículo [](info:static-properties-methods#statics-and-inheritance).
-In other words, the prototype of built-in constructor `Array` does not point to `Object`. This way `Array` and `Date` do not have `Array.keys` or `Date.keys`. And that feels natural.
+Pero las clases integradas son una excepción. No heredan estáticos el uno del otro.
-Here's the picture structure for `Date` and `Object`:
+Por ejemplo, tanto `Array` como `Date` heredan de `Object`, por lo que sus instancias tienen métodos de `Object.prototype`. Pero `Array.[[Prototype]]` no hace referencia a `Object`, por lo que no existe, por ejemplo, el método estático `Array.keys()` (o `Date.keys()`).
+
+Aquí está la imagen, estructura para `Date` y `Object`:

-Note, there's no link between `Date` and `Object`. Both `Object` and `Date` exist independently. `Date.prototype` inherits from `Object.prototype`, but that's all.
+Como puede ver, no hay un vínculo entre `Date` y `Object`. Son independientes, solo `Date.prototype` hereda de `Object.prototype`.
+
+Esa es una diferencia importante de herencia entre los objetos integrados en comparación con lo que obtenemos con 'extends`.
diff --git a/1-js/09-classes/05-extend-natives/object-date-inheritance.svg b/1-js/09-classes/05-extend-natives/object-date-inheritance.svg
index f46577f14..470aabf7f 100644
--- a/1-js/09-classes/05-extend-natives/object-date-inheritance.svg
+++ b/1-js/09-classes/05-extend-natives/object-date-inheritance.svg
@@ -1,71 +1 @@
-
-
\ No newline at end of file
+
\ No newline at end of file