diff --git a/1-js/09-classes/01-class/1-rewrite-to-class/task.md b/1-js/09-classes/01-class/1-rewrite-to-class/task.md index 05365e410..e5a6d0dcf 100644 --- a/1-js/09-classes/01-class/1-rewrite-to-class/task.md +++ b/1-js/09-classes/01-class/1-rewrite-to-class/task.md @@ -2,8 +2,8 @@ importance: 5 --- -# Rewrite to class +# Reescribir como class -The `Clock` class is written in functional style. Rewrite it the "class" syntax. +La clase `Clock` está escrita en estilo funcional. Reescríbela en sintaxis de clase. -P.S. The clock ticks in the console, open it to see. +P.D. El reloj anda en la consola, ábrela para verlo. diff --git a/1-js/09-classes/01-class/article.md b/1-js/09-classes/01-class/article.md index 835143e94..13aabccce 100644 --- a/1-js/09-classes/01-class/article.md +++ b/1-js/09-classes/01-class/article.md @@ -1,22 +1,22 @@ -# Class basic syntax +# Sintaxis básica de `class` ```quote author="Wikipedia" -In object-oriented programming, a *class* is an extensible program-code-template for creating objects, providing initial values for state (member variables) and implementations of behavior (member functions or methods). +En informática, una clase es una plantilla para la creación de objetos de datos según un modelo predefinido. Las clases se utilizan para representar entidades o conceptos, como los sustantivos en el lenguaje. Cada clase es un modelo que define un conjunto de variables —el estado—, y métodos apropiados para operar con dichos datos —el comportamiento—. ``` -In practice, we often need to create many objects of the same kind, like users, or goods or whatever. +En la práctica a menudo necesitamos crear muchos objetos del mismo tipo, como usuarios, bienes, lo que sea. -As we already know from the chapter , `new function` can help with that. +Como ya sabemos del capítulo , `new function` puede ayudar con eso. -But in the modern JavaScript, there's a more advanced "class" construct, that introduces great new features which are useful for object-oriented programming. +Pero en JavaScript moderno hay un constructor más avanzado, "class", que introduce grandes características nuevas muy útiles para la programación orientada a objetos. -## The "class" syntax +## La sintaxis "class" -The basic syntax is: +La sintaxis básica es: ```js class MyClass { - // class methods + // métodos de clase constructor() { ... } method1() { ... } method2() { ... } @@ -25,11 +25,11 @@ class MyClass { } ``` -Then use `new MyClass()` to create a new object with all the listed methods. +Entonces usamos `new MyClass()` para crear un objeto nuevo con todos los métodos listados. -The `constructor()` method is called automatically by `new`, so we can initialize the object there. +El método `constructor()` es llamado automáticamente por `new`, así podemos inicializar el objeto allí. -For example: +Por ejemplo: ```js run class User { @@ -44,33 +44,33 @@ class User { } -// Usage: +// Uso: let user = new User("John"); user.sayHi(); ``` -When `new User("John")` is called: -1. A new object is created. -2. The `constructor` runs with the given argument and assigns `this.name` to it. +Cuando se llama a `new User("John")`: +1. Un objeto nuevo es creado. +2. El `constructor` se ejecuta con el argumento dado y lo asigna `this.name`. -...Then we can call object methods, such as `user.sayHi()`. +...Entonces podemos llamar a sus métodos, como `user.sayHi()`. -```warn header="No comma between class methods" -A common pitfall for novice developers is to put a comma between class methods, which would result in a syntax error. +```warn header="No va una coma entre métodos de clase" +Un tropiezo común en desarrolladores principiantes es poner una coma entre los métodos de clase, lo que resulta en un error de sintaxis. -The notation here is not to be confused with object literals. Within the class, no commas are required. +La notación aquí no debe ser confundida con la sintaxis de objeto literal. Dentro de la clase no se requieren comas. ``` -## What is a class? +## ¿Qué es una clase? -So, what exactly is a `class`? That's not an entirely new language-level entity, as one might think. +Entonces, ¿qué es exactamente `class`? No es una entidad completamente nueva a nivel de lenguaje como uno podría pensar. -Let's unveil any magic and see what a class really is. That'll help in understanding many complex aspects. +Develemos la magia y veamos lo que realmente es una clase. Ayudará a entender muchos aspectos complejos. -In JavaScript, a class is a kind of function. +En JavaScript, una clase es un tipo de función. -Here, take a look: +Aquí, hecha un vistazo: ```js run class User { @@ -78,24 +78,24 @@ class User { sayHi() { alert(this.name); } } -// proof: User is a function +// La prueba: User es una función *!* alert(typeof User); // function */!* ``` -What `class User {...}` construct really does is: +Lo que la contrucción `class User {...}` hace realmente es: -1. Creates a function named `User`, that becomes the result of the class declaration. The function code is taken from the `constructor` method (assumed empty if we don't write such method). -2. Stores class methods, such as `sayHi`, in `User.prototype`. +1. Crea una función llamada `User`, la que se vuelve el resultado de la declaración de la clase. El código de la función es tomado del método `constructor` (se asume vacío si no se escribe tal método). +2. Almacena los métodos de clase, tales como `sayHi`, en `User.prototype`. -After `new User` object is created, when we call its method, it's taken from the prototype, just as described in the chapter . So the object has access to class methods. +Después de que el objeto `new User` es creado, cuando llamamos a sus métodos estos son tomados del prototipo, tal como se describe en el capítulo . Así el objeto tiene acceso a métodos de clase. -We can illustrate the result of `class User` declaration as: +Podemos ilustrar el resultado de la declaración de `class User` como: ![](class-user.svg) -Here's the code to introspect it: +Aquí el código para inspeccionarlo: ```js run class User { @@ -103,50 +103,50 @@ class User { sayHi() { alert(this.name); } } -// class is a function +// una clase es una función alert(typeof User); // function -// ...or, more precisely, the constructor method +// ...o, más precisamente, el método contructor alert(User === User.prototype.constructor); // true -// The methods are in User.prototype, e.g: +// Los métodos están en User.prototype, por ejemplo: alert(User.prototype.sayHi); // alert(this.name); -// there are exactly two methods in the prototype +// Hay exactamente dos métodos en el prototipo alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi ``` -## Not just a syntactic sugar +## No es solamente azúcar sintáctica -Sometimes people say that `class` is a "syntactic sugar" (syntax that is designed to make things easier to read, but doesn't introduce anything new), because we could actually declare the same without `class` keyword at all: +A veces se dice que `class` es "azúcar sintáctica" (sintaxis que es diseñada para que sea más fácil de leer pero no introduce nada nuevo), porque en realidad podemos declarar lo mismo sin la palabra clave `class` en absoluto: ```js run -// rewriting class User in pure functions +// reescribiendo la clase User puramente con funciones -// 1. Create constructor function +// 1. Crear la función constructor function User(name) { this.name = name; } -// a function prototype has "constructor" property by default, -// so we don't need to create it +// un prototipo de función tiene la propiedad "constructor" por defecto, +// así que no necesitamos crearla -// 2. Add the method to prototype +// 2. Agregar el método al prototipo User.prototype.sayHi = function() { alert(this.name); }; -// Usage: +// Uso: let user = new User("John"); user.sayHi(); ``` -The result of this definition is about the same. So, there are indeed reasons why `class` can be considered a syntactic sugar to define a constructor together with its prototype methods. +El resultado de esta definición es el mismo. Así, efectivamente hay razones para que `class` sea considerada azúcar sintáctica para definir un constructor junto con sus métodos de prototipo. -Still, there are important differences. +Aún así hay diferencias importantes. -1. First, a function created by `class` is labelled by a special internal property `[[FunctionKind]]:"classConstructor"`. So it's not entirely the same as creating it manually. +1. Primero, una función creada por `class` es etiquetada por una propiedad interna especial `[[FunctionKind]]:"classConstructor"`. Entones no es exactamente lo mismo que crearla manualmente. - The language checks for that property in a variety of places. For example, unlike a regular function, it must be called with `new`: + El lenguaje verifica esa propiedad en varios lugares. Por ejemplo, a diferencia de las funciones regulares, esta debe ser llamada con `new`: ```js run class User { @@ -154,10 +154,10 @@ Still, there are important differences. } alert(typeof User); // function - User(); // Error: Class constructor User cannot be invoked without 'new' + User(); // Error: El contructor de clase User no puede ser invocado sin 'new' ``` - Also, a string representation of a class constructor in most JavaScript engines starts with the "class..." + Además una representación string de un contructor de clase en la mayoría de los motores JavaScript comienzan con "class..." ```js run class User { @@ -166,23 +166,23 @@ Still, there are important differences. alert(User); // class User { ... } ``` - There are other differences, we'll see them soon. + Hay otras diferencias que veremos pronto. -2. Class methods are non-enumerable. - A class definition sets `enumerable` flag to `false` for all methods in the `"prototype"`. +2. Los métodos de clase no son enumerables. + La definición de clase establece la bandera `enumerable` a `false` para todos los métodos en `"prototype"`. - That's good, because if we `for..in` over an object, we usually don't want its class methods. + Esto es bueno porque si hacemos `for..in` a un objeto usualmente no queremos sus métodos de clase. -3. Classes always `use strict`. - All code inside the class construct is automatically in strict mode. +3. Las clases siempre asumen `use strict`. + Todo el código dentro del contructor de clase está automáticamente en modo estricto. -Besides, `class` syntax brings many other features that we'll explore later. +Además la sintaxis de `class` brinda muchas otras características que exploraremos luego. -## Class Expression +## Expresión de clases -Just like functions, classes can be defined inside another expression, passed around, returned, assigned, etc. +Al igual que las funciones, las clases pueden ser definidas dentro de otra expresión, pasadas, devueltas, asignadas, etc. -Here's an example of a class expression: +Aquí hay un ejemplo de una expresión de clase: ```js let User = class { @@ -192,29 +192,29 @@ let User = class { }; ``` -Similar to Named Function Expressions, class expressions may have a name. +Al igual que las expresiones de función, las expresiones de clase pueden tener un nombre. -If a class expression has a name, it's visible inside the class only: +Si una expresión de clase tiene un nombre, este es visible solamente dentro de la clase. ```js run -// "Named Class Expression" -// (no such term in the spec, but that's similar to Named Function Expression) +// Expresiones de clase con nombre +// ("Named Class Expression" no figura así en la especificación, pero es equivalente a "Named Function Expression") let User = class *!*MyClass*/!* { sayHi() { - alert(MyClass); // MyClass name is visible only inside the class + alert(MyClass); // El nombre de MyClass solo es visible dentro de la clase } }; -new User().sayHi(); // works, shows MyClass definition +new User().sayHi(); // Funciona, muestra la definición de MyClass -alert(MyClass); // error, MyClass name isn't visible outside of the class +alert(MyClass); // error, el nombre de MyClass no es visible fuera de la clase ``` -We can even make classes dynamically "on-demand", like this: +Podemos inclusive crear clases dinámicamente "a pedido", como esto: ```js run function makeClass(phrase) { - // declare a class and return it + // declara una clase y la devuelve return class { sayHi() { alert(phrase); @@ -222,7 +222,7 @@ function makeClass(phrase) { }; } -// Create a new class +// Crea una nueva clase let User = makeClass("Hello"); new User().sayHi(); // Hello @@ -231,15 +231,15 @@ new User().sayHi(); // Hello ## Getters/setters -Just like literal objects, classes may include getters/setters, computed properties etc. +Al igual que los objetos literales, las clases pueden incluir getters/setters, propiedades calculadas, etc. -Here's an example for `user.name` implemented using `get/set`: +Aquí hay un ejemplo de `user.name`, implementado usando `get/set`: ```js run class User { constructor(name) { - // invokes the setter + // invoca el setter this.name = name; } @@ -253,7 +253,7 @@ class User { set name(value) { */!* if (value.length < 4) { - alert("Name is too short."); + alert("Nombre demasiado corto."); return; } this._name = value; @@ -264,14 +264,14 @@ class User { let user = new User("John"); alert(user.name); // John -user = new User(""); // Name is too short. +user = new User(""); // Nombre demasiado corto. ``` -Technically, such class declaration works by creating getters and setters in `User.prototype`. +Técnicamente, la declaración de clase funciona creando getters y setters en `User.prototype`. -## Computed names [...] +## Nombres calculados [...] -Here's an example with a computed method name using brackets `[...]`: +Aquí hay un ejemplo con un nombre de método calculado usando corchetes `[...]`: ```js run class User { @@ -287,19 +287,19 @@ class User { new User().sayHi(); ``` -Such features are easy to remember, as they resemble that of literal objects. +Es una característica fácil de recordar porque se asemeja a la de los objetos literales. -## Class fields +## Campos de clase (Class fields) -```warn header="Old browsers may need a polyfill" -Class fields are a recent addition to the language. +```warn header="Los navegadores viejos pueden necesitar polyfill" +Los campos de clase son un agregado reciente al lenguaje. ``` -Previously, our classes only had methods. +Antes, nuestras clases tenían solamente métodos. -"Class fields" is a syntax that allows to add any properties. +"Campos de clase" es una sintaxis que nos permite agregar una propiedad cualquiera. -For instance, let's add `name` property to `class User`: +Por ejemplo, agreguemos la propiedad `name` a la clase `User`: ```js run class User { @@ -315,9 +315,9 @@ class User { new User().sayHi(); // Hello, John! ``` -So, we just write " = " in the declaration, and that's it. +Así, simplemente escribimos " = " en la declaración, y eso es todo. -The important difference of class fields is that they are set on individual objects, not `User.prototype`: +La diferencia importante de las propiedades definidas como "campos de clase" es que estas son establecidas en los objetos individuales, no compartidas en `User.prototype`: ```js run class User { @@ -331,7 +331,7 @@ alert(user.name); // John alert(User.prototype.name); // undefined ``` -We can also assign values using more complex expressions and function calls: +También podemos asignar valores usando expresiones más complejas y llamados a función: ```js run class User { @@ -344,13 +344,13 @@ let user = new User(); alert(user.name); // John ``` -### Making bound methods with class fields +### Vinculación de métodos (binding) usando campos de clase -As demonstrated in the chapter functions in JavaScript have a dynamic `this`. It depends on the context of the call. +Como se demostró en el capítulo , las funciones en JavaScript tienen un `this` dinámico. Este depende del contexto del llamado. -So if an object method is passed around and called in another context, `this` won't be a reference to its object any more. +Entonces si un método de objeto es pasado y llamado en otro contexto, `this` ya no será una referencia a su objeto. -For instance, this code will show `undefined`: +Por ejemplo, este código mostrará `undefined`: ```js run class Button { @@ -370,14 +370,14 @@ setTimeout(button.click, 1000); // undefined */!* ``` -The problem is called "losing `this`". +Este problema es denominado "pérdida de `this`". -There are two approaches to fixing it, as discussed in the chapter : +Hay dos enfoques para solucionarlos, como se discute en el capítulo : -1. Pass a wrapper-function, such as `setTimeout(() => button.click(), 1000)`. -2. Bind the method to object, e.g. in the constructor. +1. Pasar un contenedor o wrapper-function como: `setTimeout(() => button.click(), 1000)`. +2. Vincular el método al objeto, por ejemplo en el constructor. -Class fields provide another, quite elegant syntax: +Los campos de clase brindan otra sintaxis, bastante elegante: ```js run class Button { @@ -396,32 +396,32 @@ let button = new Button("hello"); setTimeout(button.click, 1000); // hello ``` -The class field `click = () => {...}` is created on a per-object basis, there's a separate function for each `Button` object, with `this` inside it referencing that object. We can pass `button.click` around anywhere, and the value of `this` will always be correct. +Un campo de clase `click = () => {...}` es creado para cada objeto. Hay una función para cada objeto `Button`, con `this` dentro referenciando ese objeto. Podemos pasar `button.click` a cualquier lado y el valor de `this` siempre será el correcto. -That's especially useful in browser environment, for event listeners. +Esto es especialmente práctico, en el ambiente de los navegadores, para los "event listeners". -## Summary +## Resumen -The basic class syntax looks like this: +La sintaxis básica de clase se ve así: ```js class MyClass { - prop = value; // property + prop = value; // propiedad constructor(...) { // constructor // ... } - method(...) {} // method + method(...) {} // método - get something(...) {} // getter method - set something(...) {} // setter method + get something(...) {} // método getter + set something(...) {} // método setter - [Symbol.iterator]() {} // method with computed name (symbol here) + [Symbol.iterator]() {} // método con nombre calculado (aquí, symbol) // ... } ``` -`MyClass` is technically a function (the one that we provide as `constructor`), while methods, getters and setters are written to `MyClass.prototype`. +`MyClass` es técnicamente una función (la que proveemos como `constructor`), mientras que los métodos, getters y setters son escritos en `MyClass.prototype`. -In the next chapters we'll learn more about classes, including inheritance and other features. +En los siguientes capítulos aprenderemos más acerca de clases, incluyendo herencia y otras características.