Skip to content

Private and protected properties and methods #169

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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
```
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand All @@ -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);
```
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class ExtendedClock extends Clock {
constructor(options) {
super(options);
let { precision=1000 } = options;
let { precision = 1000 } = options;
this.precision = precision;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
clock.start();


/* Your class should work like this: */
/* Tu clase debería funcionar así: */

/*

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,81 +1,81 @@
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;
}
}

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:

![](rabbit-extends-object.svg)

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` |
21 changes: 10 additions & 11 deletions 1-js/09-classes/02-class-inheritance/3-class-extend-object/task.md
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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 {
Expand All @@ -39,5 +38,5 @@ class Rabbit extends Object {

let rabbit = new Rabbit("Rab");

alert( rabbit.hasOwnProperty('name') ); // true
alert( rabbit.hasOwnProperty('name') ); // Error
```
Loading