Campos y métodos de clase

Campos

Los campos de clase se declaran directamente dentro del cuerpo de una clase, no se agregan de forma explícita como una propiedad del valor this. Sin embargo, el resultado es el mismo: una propiedad definida en instancias de esa clase.

class MyClass {
    myField;
}

const myClassInstance = new MyClass();

myClassInstance;
> MyClass { myField: undefined }

Puedes inicializar un campo con un valor. A menudo, este es un valor predeterminado que la lógica dentro de la clase puede reemplazar:

class MyClass {
    myResult = false;
    set setValue( myValue ) {
        this.myResult = myValue;
    }
}
const myClassInstance = new MyClass();

myClassInstance;
> Object { myResult: false }

myClassInstance.setValue = true;

myClassInstance;\
> Object { myResult: true }

Los campos de clase son funcionalmente idénticos a las propiedades adjuntas a la clase con this. Esto significa que se puede acceder a ellas y modificarlas desde fuera de la clase como cualquier otra propiedad.

class MyClass {
    myField = true;
}

const myClassInstance = new MyClass();

myClassInstance.myField;
> true

myClassInstance.myField = false;

myClassInstance.myField;
> false;

Los campos proporcionan una base para algunas de las funciones más avanzadas de las clases.

Métodos y campos privados

Los campos y métodos Private no son accesibles fuera de una clase. Una propiedad privada se asocia con una instancia de una clase, lo que significa que cada instancia contiene su propio conjunto de campos privados y métodos, según se define en la clase.

Para convertir una propiedad en privada, agrega un elemento # al comienzo del identificador cuando lo declares:

class MyClass {
    #myPrivateField = true;
    #myPrivateMethod() {}
}
const myClassInstance = new MyClass();

myClassInstance;
> MyClass { #myPrivateField: true }
    #myPrivateField: true
    <prototype>: Object { … }
        constructor: class MyClass {}
        <prototype>: Object { … }

Los campos privados se deben declarar en el cuerpo de la clase que los contiene. Puedes modificar su valor más adelante como una propiedad de this, pero no puedes crear el campo con this.

No se puede acceder a los campos privados desde otras partes de una secuencia de comandos. Esto evita que las propiedades de datos se modifiquen fuera de los métodos get y set que se proporcionan para interactuar con los valores que contienen, y evita el acceso directo a los métodos diseñados solo para su uso dentro de la propia clase.

class MyClass {
    #myResult = false;
    set setValue( myValue ) {
        this.#myResult = myValue;
    }
}
const myClassInstance = new MyClass();

myClassInstance;
> MyClass { #myResult: false }

myClassInstance.#myResult = true;
> Uncaught SyntaxError: reference to undeclared private field or method #myResult

myClassInstance.setValue = true;

myClassInstance;\
> MyClass { #myResult: true }

Sin embargo, ten en cuenta que, en general, las consolas para desarrolladores de los navegadores son muy permisivas, aunque inconsistentes, con respecto a permitir el acceso a campos privados con fines de depuración:

class MyClass {
    #myPrivateField = true;
    #myPrivateMethod() {
        console.log( "This is inside a private method." );
    }
}
const myClassInstance = new MyClass();

myClassInstance;
> MyClass {#myPrivateField: true}

myClassInstance.#myPrivateField;
> true

myClassInstance.#myPrivateMethod();
> "This is inside a private method."
class MyClass {
    #myPrivateField = true;
    #myPrivateMethod() {
        console.log( "This is inside a private method." );
    }
}
const myClassInstance = new MyClass();

myClassInstance;
> MyClass {#myPrivateField: true}

myClassInstance.#myPrivateField;
> Uncaught SyntaxError: reference to undeclared private field or method #myPrivateField

myClassInstance.#myPrivateMethod();
> Uncaught SyntaxError: reference to undeclared private field or method #myPrivateMethod

Los campos privados tienen un alcance estricto para el cuerpo de la clase que los contiene, lo que significa que incluso las clases secundarias no pueden acceder a los campos privados asociados con una clase superior:

class MyClass {
    #myPrivateField = true;
}
class ChildClass extends MyClass {
    childMethod() {
        console.log( this.#myPrivateField );
    }
}
> Uncaught SyntaxError: reference to undeclared private field or method #myPrivateField

Campos y métodos estáticos

Los campos y métodos estáticos son miembros de una clase en sí, no miembros de las instancias de esa clase. Debido a esto, los campos estáticos proporcionan un punto central para los datos que no serán únicos de cada instancia de una clase, pero al que esas instancias podrían necesitar hacer referencia, por ejemplo, información de configuración compartida. Los métodos estáticos suelen ser funciones de utilidad para trabajar con instancias de una clase, como comparar u ordenar instancias con un campo que contienen.

Para definir campos y métodos estáticos en el cuerpo de una clase, usa la palabra clave static:

class MyClass {
    static myStaticField;
    static myStaticMethod() {}
}
const myClassInstance = new MyClass();

También puedes usar la notación de puntos para crear un método estático:

class MyClass {
    constructor() {}
}
MyClass.myStaticMethod = function() {}

No puedes acceder a propiedades estáticas desde una instancia de su clase, pero están disponibles en el constructor de la clase:

class MyClass {
    static myStaticField = true;
    static myStaticMethod() {
        console.log( "A static method." );
    }
}
const myClassInstance = new MyClass();

myClassInstance.myStaticField;
> undefined

myClassInstance.myStaticMethod();
> Uncaught TypeError: myClassInstance.myStaticMethod is not a function

MyClass.myStaticField;
> true

MyClass.myStaticMethod();
> "A static method."

No son técnicamente necesarias, pero el uso de métodos estáticos es una práctica recomendada para crear utilidades que funcionen con instancias de una clase. Algunos ejemplos pueden incluir un método estático dedicado a ordenar instancias de una clase o un método de fábrica estático que contenga la configuración necesaria para crear una instancia de una clase y, luego, muestre la instancia de la clase:

class User {
    constructor( name, email ) {
        this.name = name;
        this.email = email;
    }
    static fromObject( myObject ) {
        return new User( myObject.name, myObject.email ?? "Omitted" );
    }
}
const userObject = {
    "name" : "My Name",
    "email" : "my@email.address"
};
const secondUserObject = {
    "name" : "My Name"
};

const firstUser = User.fromObject( userObject );
const secondUser = User.fromObject( secondUserObject );

firstUser;
> Object { name: "My Name", email: "my@email.address" }

secondUser;
> Object { name: "My Name", email: "Omitted" }

Verifica tus conocimientos

¿A cuál de los siguientes tipos de campos se puede acceder solo desde la clase?

Campos privados
Campos de clase
Static fields