diff options
Diffstat (limited to 'files/es/web/javascript/reference/classes/public_class_fields/index.html')
-rw-r--r-- | files/es/web/javascript/reference/classes/public_class_fields/index.html | 386 |
1 files changed, 386 insertions, 0 deletions
diff --git a/files/es/web/javascript/reference/classes/public_class_fields/index.html b/files/es/web/javascript/reference/classes/public_class_fields/index.html new file mode 100644 index 0000000000..446c63c001 --- /dev/null +++ b/files/es/web/javascript/reference/classes/public_class_fields/index.html @@ -0,0 +1,386 @@ +--- +title: Class fields +slug: Web/JavaScript/Referencia/Classes/Class_fields +tags: + - Clases + - JavaScript +translation_of: Web/JavaScript/Reference/Classes/Public_class_fields +--- +<div>{{JsSidebar("Classes")}}</div> + +<div class="note">Las declaraciones de campos públicos y privados son una <a href="https://github.com/tc39/proposal-class-fields">característica experimental (en estado 3)</a> propuesta por el <a href="https://tc39.github.io/beta/">TC39</a>, el comite de estandares de JavaScript. El soporte y funcionamiento en navegadores es limitado, pero la funcionalidad puede ser usada a través de un paso durante el proceso del build por medio de sistemas como <a href="https://babeljs.io/">Babel</a>. Revise <a href="#Browser_compatibility">compat information</a> mas abajo.</div> + +<p>Los campos públicos y estáticos son propieades editables, enumerables, y configurables. A diferencia de su contraparte privada, estos participan en la herencia de prototipo.</p> + +<h2 id="Sintaxis">Sintaxis</h2> + +<pre class="syntaxbox notranslate">class ClassWithInstanceField { + instanceField = 'instance field' +} + +class ClassWithStaticField { + static staticField = 'static field' +} + +class ClassWithPublicInstanceMethod { + publicMethod() { + return 'hello world' + } +} +</pre> + +<h2 id="Ejemplos">Ejemplos</h2> + +<h3 id="Campos_públicos_estáticos">Campos públicos estáticos</h3> + +<p>Los campos estáticos públicos son útiles cuando desea que exista un campo solo una vez por clase, no en cada instancia de clase que cree. Esto es útil para cachés, configuración fija o cualquier otro dato que no necesite replicarse en todas las instancias.</p> + +<p>Los campos estáticos públicos se declaran utilizando la palabra clave <code>static</code>. Se agregan al constructor de la clase en el momento de la evaluación de la clase utilizando {{jsxref("Global_Objects/Object/defineProperty", "Object.defineProperty()")}}. Se accede nuevamente desde el constructor de la clase.</p> + +<pre class="brush: js notranslate">class ClassWithStaticField { + static staticField = 'static field'; +} + +console.log(ClassWithStaticField.staticField); +// expected output: "static field" +</pre> + +<p>Campos sin inicializadores son inicializados como <code>undefined</code>.</p> + +<pre class="brush: js notranslate">class ClassWithStaticField { + static staticField; +} + +console.assert(ClassWithStaticField.hasOwnProperty('staticField')); +console.log(ClassWithStaticField.staticField); +// expected output: "undefined"</pre> + +<p>Los campos estáticos públicos no se reinicializan en las subclases, pero se puede acceder a ellos a través de la cadena de prototipo.</p> + +<pre class="brush: js notranslate">class ClassWithStaticField { + static baseStaticField = 'base field'; +} + +class SubClassWithStaticField extends ClassWithStaticField { + static subStaticField = 'sub class field'; +} + +console.log(SubClassWithStaticField.subStaticField); +// expected output: "sub class field" + +console.log(SubClassWithStaticField.baseStaticField); +// expected output: "base field"</pre> + +<p>Cuando se inicializasn campos <code>this</code> se refiere al constuctor de clase. Tambien puede ser referenciado por nombre, y se puede usar <code>super</code> para obtener el constructor de la superclase si lo tiene.</p> + +<pre class="brush: js notranslate">class ClassWithStaticField { + static baseStaticField = 'base static field'; + static anotherBaseStaticField = this.baseStaticField; + + static baseStaticMethod() { return 'base static method output'; } +} + +class SubClassWithStaticField extends ClassWithStaticField { + static subStaticField = super.baseStaticMethod(); +} + +console.log(ClassWithStaticField.anotherBaseStaticField); +// expected output: "base static field" + +console.log(SubClassWithStaticField.subStaticField); +// expected output: "base static method output" +</pre> + +<h3 id="Campos_de_instancia_públicos">Campos de instancia públicos</h3> + +<p>Los campos de instancia públicos existen en cada instancia de la clase que se ha creado. Al declarar un campo publico podemos asegurarnos que dicho campo siempre esta presente, y la definicion de la clase esta auto-documentada.</p> + +<p>Los campos de instancia públicos son agregados with <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty">Object.defineProperty</a> ya sea a la hora de ser construido en la clase base (antes que el metodo constructor corra), o justo despues que <code>super()</code> returne en una subclase.</p> + +<pre class="brush: js notranslate">class ClassWithInstanceField { + instanceField = 'instance field'; +} + +const instance = new ClassWithInstanceField(); +console.log(instance.instanceField); +// expected output: "instance field"</pre> + +<p>Campos sin inicializadores son inicilizados en <code>undefined</code>.</p> + +<pre class="brush: js notranslate">class ClassWithInstanceField { + instanceField; +} + +const instance = new ClassWithInstanceField(); +console.assert(instance.hasOwnProperty('instanceField')); +console.log(instance.instanceField); +// expected output: "undefined"</pre> + +<p>Al igual que las propiedades, los nombres de campos pueden ser calculados (computed)</p> + +<pre class="brush: js notranslate">const PREFIX = 'prefix'; + +class ClassWithComputedFieldName { + [`${PREFIX}Field`] = 'prefixed field'; +} + +const instance = new ClassWithComputedFieldName(); +console.log(instance.prefixField); +// expected output: "prefixed field"</pre> + +<p>Cuando se inicializan campos <code>this</code> se refiere a la instancia de clase que esta siendo construida. Al igual que con los metodos publicos de instancia, si usted esta en una subclase puede acceder a al prototypo de la superclase usando <code>super</code>.</p> + +<pre class="brush: js notranslate">class ClassWithInstanceField { + baseInstanceField = 'base field'; + anotherBaseInstanceField = this.baseInstanceField; + baseInstanceMethod() { return 'base method output'; } +} + +class SubClassWithInstanceField extends ClassWithInstanceField { + subInstanceField = super.baseInstanceMethod(); +} + +const base = new ClassWithInstanceField(); +const sub = new SubClassWithInstanceField(); + +console.log(base.anotherBaseInstanceField); +// expected output: "base field" + +console.log(sub.subInstanceField); +// expected output: "base method output"</pre> + +<h3 id="Métodos_públicos">Métodos públicos</h3> + +<h4 id="Métodos_públicos_estáticos">Métodos públicos estáticos</h4> + +<p>La palabra reservada <code><strong>static</strong></code> define un metodo estático para una clase. Los métodos estáticos no son llamads usando una instancia de la clase. En lugar de eso son llamados sobre la clase como tal. Estos metodos estáticos son frecuentemente funciones utilitarias que permiten por ejemplo la creación y clonacion de objetos.</p> + +<pre class="brush: js notranslate">class ClassWithStaticMethod { + static staticMethod() { + return 'static method has been called.'; + } +} + +console.log(ClassWithStaticMethod.staticMethod()); +// expected output: "static method has been called."</pre> + +<p>Los métodos estáticos son agregados al constructor de la clase usando <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty">Object.defineProperty</a> duranten el evaluación de la clase. Estos metodos son "escribibles" (writable), no-enumerables y configurables.</p> + +<h4 id="Métodos_públicos_de_instancia">Métodos públicos de instancia</h4> + +<p>Como su nombre lo indica, los métodos publicos de instancia son metodos que estan disponibles para cualquier instancia de una clase.</p> + +<pre class="brush: js notranslate">class ClassWithPublicInstanceMethod { + publicMethod() { + return 'hello world'; + } +} + +const instance = new ClassWithPublicInstanceMethod(); +console.log(instance.publicMethod()); +// expected output: "hello world"</pre> + +<p>Los métodos públicos de instancia son agregeados al prototipo de clase durante la evaluacón de la clase usando <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty">Object.defineProperty</a>. Estos metodos son "escribibles" (writable), no-enumerables y configurables.</p> + +<p>Usted puede usar un generador, async y funciones generadoras asincronas</p> + +<pre class="brush: js notranslate">class ClassWithFancyMethods { + *generatorMethod() { } + async asyncMethod() { } + async *asyncGeneratorMethod() { } +}</pre> + +<p>Dentro de un metodo de instancia, <code>this</code> se referie a la instancia como tal. En las subclases, <code>super</code> le permite acceder el prototipo de la superclase, permitiendo así llamar métodos de la superclase.</p> + +<pre class="brush: js notranslate">class BaseClass { + msg = 'hello world'; + basePublicMethod() { + return this.msg; + } +} + +class SubClass extends BaseClass { + subPublicMethod() { + return super.basePublicMethod(); + } +} + +const instance = new SubClass(); +console.log(instance.subPublicMethod()); +// expected output: "hello world" +</pre> + +<p>Existen metodos especiales llamados "Getters" y "Setters" que se vinculan a una propiedad de una clase, y que son ejecutados o llamados cuando esa propiedad es consultada o moditficada. Puede usar las palabras reservaddas <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get">get</a> y <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set">set</a> para declarar una instancia pública de "getter" or "setter". [N.T. preferí decir Getter/Setter que decir Consultadores/Mofificadores]</p> + +<pre class="brush: js notranslate">class ClassWithGetSet { + #msg = 'hello world'; + get msg() { + return this.#msg; + } + set msg(x) { + this.#msg = `hello ${x}`; + } +} + +const instance = new ClassWithGetSet(); +console.log(instance.msg); +// expected output: "hello world" + +instance.msg = 'cake'; +console.log(instance.msg); +// expected output: "hello cake" +</pre> + +<h2 id="Campos_privados">Campos privados</h2> + +<h3 id="Campos_privados_estáticos">Campos privados estáticos</h3> + +<p>Private fields are accessible on the class constructor from inside the class declaration itself.</p> + +<p>The limitation of static variables being called by only static methods still holds.</p> + +<pre class="brush: js notranslate">class ClassWithPrivateStaticField { + static #PRIVATE_STATIC_FIELD; + + static publicStaticMethod() { + ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD = 42; + return ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD; + } +} + +assert(ClassWithPrivateStaticField.publicStaticMethod() === 42);</pre> + +<p>Private static fields are added to the class constructor at class evaluation time.</p> + +<p>There is a provenance restriction on private static fields. Only the class which defines the private static field can access the field. This can lead to unexpected behaviour when using <strong><code>this</code></strong></p> + +<pre class="brush: js notranslate">class BaseClassWithPrivateStaticField { + static #PRIVATE_STATIC_FIELD; + + static basePublicStaticMethod() { + this.#PRIVATE_STATIC_FIELD = 42; + return this.#PRIVATE_STATIC_FIELD; + } +} + +class SubClass extends BaseClassWithPrivateStaticField { } + +assertThrows(() => SubClass.basePublicStaticMethod(), TypeError); +</pre> + +<h3 id="Campos_privados_de_instancia">Campos privados de instancia</h3> + +<p>Private instance fields are declared with <strong># names </strong>( pronounced "hash names"), which are identifiers prefixed with #. The # is a part of the name itself and is used for declaration and accessing as well.</p> + +<p>The encapsulation is enforced by the language. It is a syntax error to refer to # names not in scope.</p> + +<pre class="brush: js notranslate">class ClassWithPrivateField { + #privateField; + + constructor() { + this.#privateField = 42; + this.#randomField = 666; # Syntax error + } +} + +const instance = new ClassWithPrivateField(); +instance.#privateField === 42; // Syntax error +</pre> + +<h2 id="Métodos_privados">Métodos privados</h2> + +<h3 id="Métodos_privados_estáticos">Métodos privados estáticos</h3> + +<p>Like their public equivalent, private static methods are called on the class, not instances of the class. Like private static fields, they are only accessible from inside the class declaration.</p> + +<p>Private static methods may be generator, async and async generator functions.</p> + +<pre class="brush: js notranslate">class ClassWithPrivateStaticMethod { + static #privateStaticMethod() { + return 42; + } + + static publicStaticMethod() { + return ClassWithPrivateStaticMethod.#privateStaticMethod(); + } +} + +assert(ClassWithPrivateStaticField.publicStaticMethod() === 42); +</pre> + +<h3 id="Métodos_privados_de_instancia">Métodos privados de instancia</h3> + +<p>Private instance methods are methods available on class instances whose access is restricted in the same manner as private instance fields.</p> + +<pre class="brush: js notranslate">class ClassWithPrivateMethod { + #privateMethod() { + return 'hello world'; + } + + getPrivateMessage() { + return #privateMethod(); + } +} + +const instance = new ClassWithPrivateMethod(); +console.log(instance.getPrivateMessage()); +// expected output: "hello world"</pre> + +<p>Private instance methods may be generator, async or async generator functions. Private getters and setters are also possible:</p> + +<pre class="brush: js notranslate">class ClassWithPrivateAccessor { + #message; + + get #decoratedMessage() { + return `✨${this.#message}✨`; + } + set #decoratedMessage(msg) { + this.#message = msg; + } + + constructor() { + this.#decoratedMessage = 'hello world'; + console.log(this.#decoratedMessage); + } +} + +new ClassWithPrivateAccessor(); +// expected output: "✨hello world✨" +</pre> + +<h2 id="Especificaciones">Especificaciones</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Especificación</th> + <th scope="col">Estado</th> + <th scope="col">Comentario</th> + </tr> + <tr> + <td><a href="https://tc39.es/proposal-class-fields/#prod-FieldDefinition">FieldDefinition production</a></td> + <td>Stage 3</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Compatibilidad_de_navegadores">Compatibilidad de navegadores</h2> + +<h3 id="Campos_públicos_de_clse">Campos públicos de clse</h3> + + + +<p>{{Compat("javascript.classes.public_class_fields")}}</p> + +<h3 id="Campos_privados_de_clase">Campos privados de clase</h3> + +<div class="hidden">The compatibility table on this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</div> + +<p>{{Compat("javascript.classes.private_class_fields")}}</p> + +<h2 id="Ver_también">Ver también</h2> + +<ul> + <li><a href="https://rfrn.org/~shu/2018/05/02/the-semantics-of-all-js-class-elements.html">The Semantics of All JS Class Elements</a></li> +</ul> |