No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Getters y setters en JavaScript

12/20
Recursos

Aportes 79

Preguntas 18

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

En ES2020 se introdujo la sintaxis campos privados en las clases. Se hace uso de un numeral como prefijo del nombre de la variable.

驴C煤al ser铆a la ventaja de usar esto? Que no existe la posibilidad de que alguien modifique la variable privada desde la instancia a menos de que use el setter que le dimos.

Con el ejemplo en esta clase, quedar铆a as铆:

class Course {
  #name;

  constructor({
    name,
    classes = []
  }) {
    this.#name = name;
    this.classes = classes;
  }

  get name() {
    return this.#name;
  }

  set name(nuevoNombrecito) {
    if (nuevoNombrecito === 'Curso Malito de Programaci贸n B谩sica') {
      console.error('Web... no');
    } else {
      this.#name = nuevoNombrecito;
    }
  }
}

Qu茅 son los getters y setters
Una funci贸n que obtiene un valor de una propiedad se llama getter y una que establece el valor de una propiedad se llama setter.

Esta caracter铆stica a sido implementada en ES2015, pudiendo modificar el funcionamiento normal de establecer u obtener el valor de una propiedad, a estas se les conoce como accessor properties.

Funcionamiento
En ocasiones queremos valores basados en otros valores, para esto los data accessors son bastante 煤tiles.

Para crearlos usamos los keywords get y set

const obj = {
  get prop() {
    return this.__prop__;
  },
  set prop(value) {
    this.__prop__ = value * 2;
  },
};

obj.prop = 12;

console.log(obj.prop); //24

Creamos un objeto, con una 煤nica propiedad, que tiene un getter y un setter. de esta manera cada vez que establezcamos un valor para prop se multiplicar谩 por dos.

Nota: utilice prop por convenci贸n, pero no implica que es un valor especial, este es un valor normal.

Otra manera de crear un accessor properties es de manera expl铆cita usando Object.defineProperty

const obj = {};

Object.defineProperty(obj, //objeto target
  'prop', //nombre propiedad
  {
    enumerable: true,
    configurable: true,
    get prop() { //getter
      return this.__prop__;
    },
    set prop(value) { //setter
      this.__prop__ = value * 2;
    },
  });
obj.prop = 12;

var atr = Object.getOwnPropertyDescriptor(obj, 'prop')
console.log(atr); 

La ventaja que tenemos de esta manera, es que podemos establecer los atributos que queremos tenga la propiedad.

Me puse a jugar un rato con los 鈥減rototypes鈥 y logre esto:

"use strict";

function Student(name, age, nationality) {
  this._name = name;
  this._age = age;
  this.nationality = nationality;
}

Student.prototype = {
  get name() {
    return this._name;
  },
  set name(newName) {
    this._name = newName;
  },

  get age() {
    return this._age;
  },

  set age(newAge) {
    this._age = newAge;
  },
};

let edgar = new Student("Edgar", 25, "Mexico");
edgar.name = "Juan";
edgar.age = 30
console.log(edgar);

Funcionando al 100 :3

Tambi茅n una forma de emular encapsulamiento en javascript es por mediode los closures.

const counter = (() => {
  let privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }

  return {
    increment: () => {
      changeBy(1);
    },

    decrement: () => {
      changeBy(-1);
    },

    value: () => {
      return privateCounter;
    }
  };
});

console.log(counter.value());  // 0.

counter.increment();
counter.increment();
console.log(counter.value());  // 2.

counter.decrement();
console.log(counter.value());  // 1.

Ejemplo sacado de MDN

Los getters y setters son geniales. Pero me paso algo extra帽o:
si pongo cursoProgBasica .name = 鈥淐ualquier nombre鈥 el SET comprueba que cumpla lo que le pedi. PEEEEROOO si pongo por consola:
cursoProgBasica._name = 鈥渃ualquier cosa鈥 ME SALTEA la barrera del SET y me toma como correcto lo que ponga! A alguien mas le paso?

Les dejo mi c贸digo sobre un manga xD usando la nueva sintaxis de #馃憞

const hasCopyright = false

class Manga {
  #mangaka;
  #name;

  constructor({ name, mangaka }) {
    this.#name = name;
    this.#mangaka = mangaka;
  }

  get mangaka() {
    return this.#mangaka;
  }

  get name() {
    return this.#name;
  }

  set name(name) {
    if (hasCopyright) {
      console.log('This Manga name has copyright!');
    } else {
      this.#name = name;
    }
  }
}

const REQUIEM_ADVENTURES = new Manga({
  name: 'Requiem Adventures',
  mangaka: 'UltiRequiem',
});

console.log(REQUIEM_ADVENTURES);
console.log(REQUIEM_ADVENTURES.mangaka);
console.log(REQUIEM_ADVENTURES.name);
REQUIEM_ADVENTURES.name = 'Adventures Requiem?';
console.log(REQUIEM_ADVENTURES.name);

Tambien les dejo mi repositorio con notas y c贸digo del curso 馃憠 UltiRequiem/oop-js-platzi.

Funci贸n generadora de n煤meros de Fibonacci usando getters y setters.

function FibonacciGenerator(){
    this._a = 0;
    this._b = 1;
}

FibonacciGenerator.prototype = {
    get next(){
        let c = this._a + this._b;
        this._a = this._b;
        this._b = c;
        return c;
    },
    set nth(number){
        if(number<=0 || number>30)
            console.error("out-bound");
        else{
            let c = 0;
            this._a = 0;
            this._b = 1;
            while(--number) 
                c = this.next;
        }
    }
}

let fib = new FibonacciGenerator();

fib.nth = 10; //10th fibonacci
fib.next;     // 89
fib.next;     //144
fib.next;     //233
  • Getters se usan para acceder a las propiedades en un objeto.

  • Setters para cambiar or silenciar una propiedad en un objeto

Los getters y setters son construcciones de los objetos que permiten acceder a valores del mismo sin revelar la forma de su implementaci贸n.

Me tomo tiempo entender bien esta clase, pero al final pude organizar los getters y setters, adicional organic茅 los setters de los atributos que eran arrays, de forma que se puedan insertar y eliminar campos de estos arrays utilizando las funciones splice y push, espero les sirva esta soluci贸n.

class Teacher{
    constructor({
        id,
        name,
        speciality,
        courses = [],
    }){
        this.id = id;
        this._name = name;
        this.speciality = speciality;
        this._courses = courses;

    }
    get name(){
        return this._name;
    }
    set name(newTeacher){
        this._name = newTeacher;
    }
    get courses (){
        return this._courses;
    }

    set courses(newCourse){
        for (let i = 0; i < this._courses.length; i++){
            if (this._courses[i] === newCourse){
                this._courses.splice(i,1);
                console.log("You have deleted " + newCourse.name + " of " + this._name + " list of Courses");
                
            }else {
                this._courses.push(newCourse);
            }
            
        }
                   
    }
}

Este s贸lo es un ejemplo b谩sico de lo que se puede hacer con getters y setters; sin embargo, le铆 en un post que como parte de las buenas pr谩cticas de programaci贸n, incluso si no vas a modificar un atributo, todos los atributos en general deber铆an ser accedidos por medio de getters y setters.
Como se ver铆a el ejemplo de la clase si fuese directamente embebido en el objeto, sin una clase, con la restricci贸n de que el valor** name **no puede ser una cadena vac铆a ni undefined.

var cursoProgBas = {
    name_value,
    clases,
    instructor,
    a帽o,
    get name(){
        return this.name_value;
    },
    set name(nuevoNombrecito){
        if(nuevoNombrecito === "" || typeof nuevoNombrecito === "undefined"){
            console.error("El nombre no es v谩lido o no ha sido asignado.")
        }
        else{
            this.name_value = nuevoNombrecito;
        }
    }   
}

Entiendo que con el uso de Getters and Setters podremos evitar errores al interactuar con los usuarios, ya que me permite selecionar los atributos de las clases y condicionarlos con validaciones de manera que el usuario cambie solo lo que nos interesa

Hola
Les comparto mi codigo, el objeto estutdiante tiene la restricci贸n de que el platziRank solo puede recibir number si es tipo 鈥渟tring鈥 mostrar谩 un error.

class Student {
    constructor({
        name,
        email,
        username,
        twitter = undefined,
        instagram = undefined,
        approvadesCourses = [],
        learningPaths = [],
        platziRank = 0,
    }) {
        this.name = name;
        this.email = email;
        this.username = username;
        this.socialMedia = {
            twitter,
            instagram,
        };
        this.approvadesCourses = approvadesCourses;
        this.learningPaths = learningPaths;
        this._platziRank = platziRank;
    }
    get platziRank(){
        return this._platziRank();
    }
    set platziRank (newPlatziRank) {
        if (typeof newPlatziRank === "number"){
            this._platziRank = newPlatziRank;
        } else {
            console.error("No puedes realizar esta cambio");
        }
    }
};

Holas les comparto parte de mi c贸digo 馃槂

muy interesante las clases he aprendido bastante

Compa帽eros una cosa que me acabo de dar cuenta, que los m谩s avanzados ya lo sabr谩n, pero realmente es un dolor de cabeza tener todas las clases, objetos, instancias, etc en el mismo .js ya que ahora que ejecute en la consola me salieron errores que revisando es por el orden de ejecuci贸n de las clases u objetos que deben ser declarados o inicializados previamente y como tenia TODO en el mismo .js ah铆 tratando de 鈥渙rdenarlos鈥 (que seg煤n yo estaba todo ordenado) ca铆 en un bucle en el que todas las clases deben ser declaradas entre todas antes una y otra jaja osea queda una mezcla completa de c贸digo sin ning煤n orden, as铆 que ahora entiendo porque lo hacen en diferentes archivos o bueno supongo que una de estas debe ser una raz贸n

Interesante siempre habia visto POO pero 煤nicamente en Java y en JS es como BOOM!! Constante 馃く

Y me recuerda mucho a la POO en Python. Si porque Python tambi茅n tiene POO

Hackeado 馃槑馃槑

Para utilizar getter o setter fuera de clases consegu铆 en al documentaci贸n que se utiliza un m茅todo est谩tico.

El m茅todo est谩tico Object.defineProperty() define una nueva propiedad sobre un objeto, o modifica una ya existente, y devuelve el objeto modificado.

tiene la siguiente sintaxis :
-Object.defineProperty(obj, prop, descriptor)

Este m茅todo nos permite modificar el comportamiento por defecto de las propiedades. Es decir, nos permite definir una propiedad como no enumerable, no modificable o incluso evitar que pueda ser eliminada del objeto

dejo el enlace por si quieren profundizar mas en el tema

https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

馃搶 Los getters y setters sirven para definir los Accessors, es decir, permiten modificar el funcionamiento de acceso para obtener los valores de las propiedades de los objetos.

Paso mi code con una breve (boba) autenticaci贸n

get attributes(){
      return {
        name: this._name,
        description: this._description,
        image: this._image
      }
    }

    set name({name, auth}){
        if(auth !== 'soyadmin'){
          console.error('Invalid Authorization')
          return false
        } else {
          this._name = name;
        }
    }

Yo proteg铆 el cambio de nombre con una contrase帽a

class Course {
  constructor({
    name,
    calsses = []
  }) {
    // Al agregarle el _ (gui贸n bajo) ocultamos el atributo name
    this._name = name;
    this.calsses = calsses;

  }

  get name() {
    return this._name;
  }

  set name(nuevoNombre) {
    if (nuevoNombre === "") {
      console.error("Error: Debes de ponerle un nombre al curso")

    } else {
      let contrase帽aCurso = prompt("Introduce la contrase帽a:");
      if (contrase帽aCurso === 'password') {
        this._name = nuevoNombre;
      } else {

        console.error("Error: No tienes permiso para cambiar el nombre del curso!")
      }
    }
  }

}

La finalidad de poner un underline antes del atributo, no es que lo haga privado, si no cuando invoquen ese atributo al no empezar por la letra, no puedan cambiaro obtener el valor direcro del atributo, sin embargo sigue visible, en cambio cuando invocan por la primer letra del atributo a quien llaman es al set o get del atributo, y ya con metodos podemos hacer distintas validaciones antes de asignarle el valor al atributo local o obtener la informacion de su valor
Aca les comparto un ejemplo donde el id 0 no cuenta como id valido para las rutas de aprendizaje

LearningPath

export default class LearningPath {
    constructor({
      id,
      title,
      courses = [],
    }) {
      this._id = id;
      this._title = title;
      this._courses = courses;
      this.coursesQuantity = courses.length;
    }

    get id(){
      return this._id;
    }

    set id(newId){
      if(newId === 0){
        console.log("El id " + newId + " no cuenta como indice de LearningPath")
      }
      this._id = newId;
    }

Main

import LearningPath from './LearningPath.js'

const escuelaDesarrolloWeb = new LearningPath({
  id: 3,
  title: 'Escuela de Desarrollo Web',
  courses: [cursoProgramacionBasica],
});
console.log(escuelaDesarrolloWeb);
escuelaDesarrolloWeb.id=0

Hay dos tipos de propiedades de un objeto.
.

  • Propiedad de datos
  • Propiedades de acceso (accessors)

Estas propiedades son funciones que se ejecutan para obtener (get) y asignar (set) un valor, pero que para un c贸digo externo se ven como propiedades normales.

Les dejo una documentaci贸n para que lo puedan ver tambi茅n con objetos literales y otros ejemplos.

Documentaci贸n: "Getters y 鈥渟etters鈥 - javascript.info/property-accessors

Ac谩 comparto una validaci贸n para el correo, claramente puede ser mayor. Espero les sirva.

Por ahi vi que en typescript si es posible agregar private, public and protected

Reto 1:

function sintaxProto(param1, param2) {
    this._param1 = param1;
    this._param2 = param2;
}
sintaxProto.prototype = {
    get param1() {
        return this._param1;
    },
    set param1(newParam) {
        this._param1 = newParam;
    },
    get param2() {
        return this._param2;
    },
    set param2(newParam) {
        this._param2 = newParam;
    },
}

Reto 2:

class Student {
    constructor({
        name,
        email,
        username,
        twitter = undefined,
        instagram = undefined,
        facebook = undefined,
        approvedCourses = [],
        learningPaths = [],
    }){
        this._name = name;
        this._email = email;
        this._username = username;
        this._socialMedia = {
            twitter,
            instagram,
            facebook,
        };
        this._approvedCourses = approvedCourses;
        this._learningPaths = learningPaths;
    }

    get name() { return this._name; }
    set name(newname) { this._name = newname; }

    get email() { return this._email; }
    set email(newemail) { this._email = newemail; }

    get username() { return this._username; }
    set username(newusername) { this._username = newusername; }
    
    get socialMedia() { return this._socialMedia; }
    set socialMedia(newSocialMedia) { this._socialMedia = newSocialMedia; }
    
    get approvedCourses() { return this._approvedCourses; }
    set approvedCourses(newApprovedCourses) { this._approvedCourses = newApprovedCourses; }
    
    get learningPaths() { return this._learningPaths; }
    set learningPaths(newLearningPaths) { this._learningPaths = newLearningPaths; }
}

class approvedCourses {
    constructor({
        name,
        courses = [],
        calificacion,
    }){
        this._name = name;
        this._courses = courses;
        this._calificacion = calificacion;
    }

    get name() { return this._name; }
    set name(newName) { this._name = newName; }

    get courses() { return this._courses; }
    set courses(newCurses) { this._courses = newCurses; }

    get calificacion() { return this._calificacion; }
    set calificacion(newCalificacion) { this._calificacion = newCalificacion; }
}
class Clases {
    constructor({
        name,
        recursos = [],
        comentarios = [],
    }){
        this._name = name;
        this._recursos = recursos; 
        this._comentarios = comentarios; 
    }

    get name() { return this._name; }
    set name(newName) { this._name = newName; }

    get recursos() { return this._recursos; }
    set recursos(newRecursos) { this._recursos = newRecursos; }

    get comentarios() { return this._name; }
    set comentarios(newComentarios) { this._comentarios = newComentarios; }
}
class Comentario {
    constructor({
        student,
        fecha,
        texto,
        tipo, //pregunta o aporte
        comentRespuesta = [], //Comentarios respuestas
    }){
        this._student = student;
        this._fecha = fecha; 
        this._texto = texto; 
        this._tipo = tipo; 
        this._comentRespuesta = comentRespuesta; 
    }

    get student() { return this._student; }
    set student(newStudent) { this._student = newStudent; }

    get fecha() { return this._fecha; }
    set fecha(newFecha) { this._fecha = newFecha; }

    get texto() { return this._texto; }
    set texto(newTexto) { this._texto = newTexto; }

    get tipo() { return this._tipo; }
    set tipo(newTipo) { this._tipo = newTipo; }

    get comentRespuesta() { return this._comentRespuesta; }
    set comentRespuesta(newComentRespuesta) { this._comentRespuesta = newComentRespuesta; }
}

class Course {
    constructor({
        name,
        clases = [],
    }){
        this._name = name; 
        this._clases = clases; 
    }
    get name(){
        return this._name;
    }
    set name(nuevoNombrecito){
        if (nuevoNombrecito === "Curso Malito de Programaci贸n B谩sica"){
            console.error("Web... no");
        } else {
            this._name = nuevoNombrecito;
        }
    }

    get clases() { return this._clases; }
    set clases(newClases) { this._clases = newClases; }
}

class LearningPaths {
    constructor({
        name,
        courses = [],
    }){
        this._name = name;
        this._courses = courses;
    }

    get name() { return this._name; }
    set name(newName) { this._name = newName; }

    get courses() { return this._courses; }
    set courses(newCourses) { this._courses = newCourses; }
}
// Reto: creando getter y setter en objetos de prototipos
function Course2({ name, clases = [] }) {
    this._name = name;
    this.clases = clases;
}

Course2.prototype.getName = function() {
    return this._name;
}

Course2.prototype.setName = function (newName) {
    if (newName === 'Nombre Malicioso') {
        console.error('Este nombre no est谩 permitido');
    } else {
        return this._name = newName;
    }
}

const courseProgrBasica2 = new Course2({
    name: 'Prograamci贸n B谩sica',
});

console.log(courseProgrBasica2.getName());
courseProgrBasica2.setName('Otro Curso');
console.log(courseProgrBasica2.getName());

Tengo entendido que en ECMAScript 5 definimos Getters y Setters con el m茅todo defineProperties del objeto Object.

Aqu铆 les coloco un ejemplo con el prototipo de Courses:


// Definimos una clase llamada Course e inicializamos sus atributos
function Course({ name, classes = [] }) {
  this.name = name;
  this.classes = classes;
}

// Usamos Object.defineProperty para agregar propiedades a un objeto
// El primer par谩metro hace referencia al objeto al que se le agregar谩 la propiedad
// El segundo par谩metro es el nombre de la propiedad
// El tercer par谩metro es un objeto con las propiedades de la propiedad,
// En este caso definimos un get y un set como en la clase
Object.defineProperty(Course.prototype, "name", {
  get: function () {
    return this._name;
  },

  set: function (value) {
    this._name = value;
  },
});

// Inicializamos una instancia del objeto
const ReactCourse = new Course({
  name: "React",
  classes: [
    {
      name: "React Basics",
      description: "Learn the basics of React",
      duration: "1 hour",
      date: "2020-01-01",
    },
    {
      name: "React Hooks",
      description: "Learn the basics of React Hooks",
      duration: "1 hour",
      date: "2020-01-01",
    },
  ],
});

// Luego usamos los metodos get y set, para editar y leer la propiedad name
ReactCourse.name = "New React Name"
console.log(ReactCourse.name)

Happy coding 馃槃

<code> 

// clase
class User{
    constructor({
        name,
        age,
        nationality
    }){
        this._name = name;
        this._age = age;
        this.nationality = nationality;
    }

    // get
    get name(){
        return this._name;
    }
    // set
    set name(nuevoName){
        if (nuevoName === "") {
            console.error("Hey introduce un nombre")
        } else {
            this._name = nuevoName;
        }
    }

    // get
    get age(){
        return this._age;
    }
    // set
    set age(nuevoAge){
        if (nuevoAge === "") {
            console.error("Hey introduce una edad")
        } else {
            this._age = nuevoAge;
        }
    }
}

const usuario = new User({
    name: "Hacker02",
    age: 24,
    nationality: "Per煤"
})

Getter y Setter en Protipos

<code> 
function Teacher(name) {
    this._nombre = name
}

Teacher.prototype = {
    // Get
    get name (){
        return this._nombre;
    },
    // set
    set name(otherName){
        if (otherName === "") {
            console.error("Profesor... su nombre")
        } else {
            this._nombre = otherName;
        }
    }
}

const Profesor = new Teacher("alejandro")

![](

En JavaScript, los setters y getters son m茅todos especiales que te permiten controlar el acceso y la modificaci贸n de propiedades de un objeto. Aunque la sintaxis de clases ofrece una forma m谩s declarativa de crear setters y getters, tambi茅n puedes utilizar prototipos para lograr el mismo resultado. Aqu铆 te muestro c贸mo hacerlo:


function Persona(nombre, edad) {
  this._nombre = nombre;
  this._edad = edad;
}

Persona.prototype = {
  // Getter para obtener el nombre
  get nombre() {
    return this._nombre;
  },

  // Setter para establecer el nombre
  set nombre(nuevoNombre) {
    this._nombre = nuevoNombre;
  },

  // Getter para obtener la edad
  get edad() {
    return this._edad;
  },

  // Setter para establecer la edad
  set edad(nuevaEdad) {
    if (nuevaEdad >= 0) {
      this._edad = nuevaEdad;
    } else {
      console.log("La edad no puede ser un valor negativo.");
    }
  }
};

// Crear una instancia de Persona
var persona = new Persona("Juan", 25);

// Utilizar los setters y getters
console.log(persona.nombre);  // Output: Juan
console.log(persona.edad);    // Output: 25

persona.nombre = "Pedro";
persona.edad = 30;

console.log(persona.nombre);  // Output: Pedro
console.log(persona.edad);    // Output: 30


En el ejemplo anterior, creamos un constructor Persona y definimos los getters y setters utilizando la propiedad prototype del constructor. Cada getter tiene el mismo nombre que la propiedad a la que accede, mientras que cada setter tiene el mismo nombre pero precedido por la palabra clave set.

Al utilizar los getters, podemos obtener los valores de las propiedades _nombre y _edad. Por otro lado, al utilizar los setters, podemos modificar los valores de estas propiedades. En el caso del setter de edad, hemos agregado una validaci贸n para asegurarnos de que la edad no sea un valor negativo.

En JavaScript, los getters y setters tambi茅n se pueden utilizar con prototipos, sin necesidad de utilizar la sintaxis de clases de JavaScript. En lugar de definir un getter o setter utilizando la sintaxis de clase, se pueden definir como m茅todos de un objeto prototipo.

Los GETTERS y SETTERS son un peaje:

Te dejan psar, pero primero pasa por ellos.

Estas es mi soluci贸n al reto:

function Student(name, age, naationality, nameOfMom ){

    this._name = name;
    this.age = age;
    this.naationality = naationality;
    this.nameOfMom = nameOfMom;

   
}

Student.prototype = {
    get name(){
        return this._name;
    },
    set name(newName){
        this._name = newName;
    }
}
<code> 

En respuesta a reto 1:

function Name() {
	constructor({
	name,
	lastName,}) {
	this.name = name;
	this.lastName = lastName}
}

Name.prototype = {
	get fullName(){
	return this.name + ' ' + this.lastName;
	}

	set fullName(newName, newLastName){
	this.name = newName;
	this.lastName = newLastName;
	}
}

//se emplea la sintaxis "antigua" de JavaScript, accediendo a la "funci贸n" como prototipo y definiendo sus m茅todos get y set, adem谩s accediendo a las variables del prototipo sin comillas francesas, siendo implementadas en ES6 (2015) como forma de evitar la concatenaci贸n y emplear la forma ${}.

Aqui dejo el reto:

class Student{
    constructor({
        username,
        password,
        name,
        email,
        nacionality,
        twitter = undefined,
        instagram = undefined,
        facebook = undefined,
        subscription = "free",
        coursesAproved = [],
        learningPaths = [],
        portfolio,
        tutorials,
        
    }){
        this._username = username
        this._password = password
        this.name = name
        this.email = email
        this.nacionality = nacionality
        this.socialMedia = {
            twitter,
            instagram,
            facebook,
        } 
        this.subscription = subscription
        this.coursesAproved = coursesAproved
        this.learningPaths = learningPaths
        this.portfolio = portfolio
        this.tutorials = tutorials
    }

    get username(){
        this._username
    }

    set username(newUsername){
        this._username = newUsername
    }

    get password(){
        this._password
    }

    set password(newPassword){
        this._password = newPassword
    }
}
/*
Implementaci贸n de encapsulamiento en el a帽o 2022 con base al ejemplo dado por el profe
*/
class Course{
    #courseName;
    #nombresNoPermitidos;
    constructor({
        courseName,
        classes = [],
        nombresNoPermitidos = []
    }){
        this.#courseName = courseName;
        this.classes = classes;
        this.#nombresNoPermitidos = nombresNoPermitidos;
    }
    get courseName(){
        return this.#courseName;
    }
    set courseName(newCourseName){
        let cont = 0;
        for(let k = 0; k < this.#nombresNoPermitidos.length; k++){
            let nameLocked = this.#nombresNoPermitidos[k];
            if(nameLocked.toLowerCase() === newCourseName.toLowerCase()){
                ++cont;
                console.error("Error!! el nombre " + newCourseName + " no est谩 permitido");
                break;
            }
        }

        if(cont == 0){
            this.#courseName = newCourseName;
        }
        
    }
    addClass(clase){
        this.classes.push(clase);
    }
    toString(){
        let mensaje = `nombre del curso: ${this.courseName}`;
        if(this.classes.length > 0){
            this.classes.forEach(clase => mensaje += 				`\r\n${clase.toString()}`);
        }
        return mensaje;
    }
}

Aqu铆 tengo algunos otros m茅todos de mas como el de escribir la informaci贸n de mi instancia.

class Class{
  constructor({
    nameClass,
    video = "No tiene",
    resources = "No tiene",
  }){
    this.nameClass = nameClass
    this.video = video
    this.resources = resources
  }
  get sayInfoClass(){
    console.log(`Nombre de clase es: ${this.nameClass} video: ${this.video} recursos: ${this.resources}`);
  }
  get getClass(){
    return this
  }
}

class Courses{
  constructor({
    nameCourse,
    classes = [],
  }){
    this._nameCourse = nameCourse
    this.classes = classes
  }
  get nameCourse(){
    return this._nameCourse;
  }
  set changeName (newCourse){
    if (newCourse == "Curso Malito de Programacion Basica"){
      console.error("Web... no");
    }else{
      this._nameCourse = newCourse;
    }
  }

  set addClass(newClass){
    this.classes.push(newClass);
  }
  set deleteCourses(deleteClasses){
    this.classes = this.classes.filter(classes =>  classes != deleteClasses)    
  }
  get sayClasses(){
    let result = "";
    this.classes.forEach(classe => {
        result +=`${classe.nameClass} - `
    });
    console.log(result);        
  }
  get getClasses(){
    return this.classes
  }
}

class LearningPath {
  constructor({
    nameLearningPath,
    courses = []
  }){
      this.nameLearningPath = nameLearningPath;
      this.courses = courses;
  }
  set addCourse(newCourse){
      this.courses.push(newCourse);
  }
  set deleteCourses(deleteCourse){
    this.courses = this.courses.filter(course =>  course != deleteCourse)    
  }
  get sayCourses(){
    let result = "";
    this.courses.forEach(course => {
        result +=`${course.nameCourse} - `
    });
    console.log(result);        
  }
  get getCourses(){
    return this.courses
  }
}

class Student {
  constructor({
        name,
        email,
        username,
        twitter = undefined,
        instagram = undefined,
        facebook = undefined,
        approvedCourses = [],
        learningPaths = [],
    }){
    this.name = name;
    this.email = email;
    this.username = username;
    this.socialMedia = {
      twitter,
      instagram,
      facebook,
    };
    this.approvedCourses = approvedCourses;
    this.learningPaths = learningPaths;
    }

    set addLearningPaths(newLearningPaths){
        this.learningPaths.push(newLearningPaths)        
    }

    set deleteLearningPaths(deleteLearningPath){
        this.learningPaths = this.learningPaths.filter(item => item != deleteLearningPath)

    }
    get sayLearningPaths(){
        let result = "";
        this.learningPaths.forEach(nameLearningPath => {
            result +=`${nameLearningPath.nameLearningPath} - `
        });
        console.log(result);        
    }
    get getLearningPaths(){
      return this.learningPaths
    }
}

// CREACION DE CLASES
const clase1 = new Class({
  nameClass:'Clases en javascript',
  video:'https://platzi.com/clases/2332-javascript-poo/38621-clases-en-javascript/'
})
const clase2 = new Class({
  nameClass:'Ventajas de la programaci贸n orientada a objetos',
  video:'https://platzi.com/clases/2332-javascript-poo/38622-ventajas-de-la-programacion-orientada-a-objetos/'
})
const clase3 = new Class({
  nameClass:'Que es Abstracion',
  video:'https://platzi.com/clases/2332-javascript-poo/38623-que-es-abstraccion/'
})
const clase4 = new Class({
  nameClass:'Abstracion',
  video:'https://platzi.com/clases/2332-javascript-poo/38624-abstraccion-en-javascript/'
})

// CREACION DE CURSOS
const cursoProgramacionBasica = new Courses({
  nameCourse:"Curso Gratis de Programacion Basica",
  classes:[
    clase1,
    clase2
  ]
})
const cursoDefinitivoHTML = new Courses({
  nameCourse:"Curso Definitivo de HTML y CSS",  
  classes:[
    clase1,
    clase3
  ]
})
const cursoPracticoHTML = new Courses({
  nameCourse:"Curso Practico de HTML y CSS",  
  classes:[
    clase1,
    clase4
  ]
})
const cursoBasicoPOO = new Courses({
  nameCourse:"Curso Gratis de Programacion Basica",
  classes:[
    clase2,
    clase3
  ]
})
const cursoBasicoJsPOO = new Courses({
  nameCourse:"Curso Gratis de Programacion Basica",
  classes:[
    clase3,
    clase4
  ]
})

// CREACION DE ESCUELAS
const escuelaWeb = new LearningPath({ 
  nameLearningPath : "Escuela de desarrollo web",
  courses:[
    cursoProgramacionBasica,
    cursoDefinitivoHTML,
    cursoPracticoHTML]
});
const escuelaJs = new LearningPath({ 
  nameLearningPath : "Escuela de desarrollo web",
  courses:[
    cursoPracticoHTML,
    cursoBasicoPOO,
    cursoBasicoJsPOO]
});

// CREACION DE ESTUDIANTES
const juanStudent = new Student({
  name: "JuanDC",
  username: "juandc",
  email: "[email protected]",
  twitter: "fjuandc",
  learningPaths: [
    escuelaWeb,
  ],
});


const miguelitoStudent = new Student({
  name: "Miguelito",
  username: "migelitofeliz",
  email: "[email protected]",
  instagram: "migelito_feliz",
  learningPaths: [
    escuelaWeb,
    escuelaJs
  ],
});

<code> 
class Course {
    constructor({
        name,
        classes = [],
    }){
        this._name = name;
        this.classes = classes;
    }

    get name (){
        return this._name;
    }

    set name(nuevoNombrecito){
        if(nuevoNombrecito === "Curso Malito de Programacion"){
            console.error ("web .... no response");
        }else{
            this._name = "nuevoNombrecito";
        }
         
        
    }

};



const cursoProgBasica = new Course({
    name: "Curso de Programacion Basica Gratis",
    classes:[
            ClaseDeComputacion    ]

});

cursoProgBasica.name = "Curso de Programacion Basica Gratis"; 

si acceden a la consola para correrlo no se puede cambiar el nombre "nuevoNombrecito " con el metodo que indica en clase , pero si accedemos con la opcion ._name = 鈥測 si intenta cambiar el nombre , este se registrara e incluso cambiara el que pusimos en console.error.鈥 . pero si lo ponemos sin ser string, se deja pasar los cambios como la clase que se muestra, me parecio interesante este experimento porque el codigo se cambia rapidamente su comportamiento por un solo dato, que pueden parecer similar.

Dejo mis apuntes del curso con notas, interpretaciones y ejemplos;

https://www.notion.so/Curso-B-sico-POO-JS-8b1ae724db364a06b5cac3055526c7b1

function Studentt (name, age, cursosAprobados) {
    this._name = name;
    this.age  = age;
    this.cursosAprobados = cursosAprobados;
    // this.aprobarCurso = function (nuevoCurso) {
    //     this.cursosAprobados.push(nuevoCurso); 
    // }
}

Studentt.prototype.aprobarCurso = function (nuevoCurso) {
    this.cursosAprobados.push(nuevoCurso);
}


Studentt.prototype = {

    get name() {
        return this._name;
    },

    set name(name) {
        this._name = name;
    }
}


const mateo = new Studentt('Mateo', 25, ["Programacion web"])

la clase escrita como funcion:

function courseForFunction(name , clases=[]){
    let saveName =  name ;
    let saveClases = clases;
    return {
        getName:()=>{
            return saveName;
        },
        setName:(newName)=>{
            saveName =  newName;
        },
        getClases:()=>{return saveClases},
        setClases:(variable)=>{saveClases=variable},

    }
    
}

:0 no sabia lo de console.error :0

mientras llenaba mi app me dio flojera escribir los getters y setters y como no encontre todavia un plugin que los haga con estas dos funciones los puedes cocechar por console.log( )


function firstToUpper(texto){
    segunda = texto.slice(1);
    primera =  texto.charAt(0);
    formatoDeseado = primera.toUpperCase() + segunda;
    return  formatoDeseado;    
}

function getAndSet(arr){
devolver ='';
for(let i =0; i<arr.length ; i++){
parametro = arr[0];


newParametro =  firstToUpper(parametro);
devolver +=   
`get ${parametro}(){return this._${parametro};}
set ${parametro}(new${newParametro}){
        this._${parametro} = new${newParametro}
    }
`
}//fin for
console.log( devolver );
}

Hice el proyecto a mi manera para practicar los distintos conceptos , me quedo asi:

Lo quise hacer con clases, impidiendo que las las rutas de aprendizaje no se puedan cambiar a categor铆as no existentes. Si se quisiera limitar a que la ruta 鈥淓scuela de desarrollo web鈥 no pueda cambiarse a ninguna otra categor铆a, se debe de implementar encapsulamiento en la clase 鈥淓scuela de sarrollo web鈥 o el nombre que se le de para poner las condicionales en la ruta de aprendizaje

class LearningPath {
    constructor({category = [], name, courses = []}){
        this._category = category;
        this.name = name;
        this.courses = courses;
    }

    get category(){
        return this._category;
    }

    set category(newCategory){
        if(newCategory !== ["Desarrollo e Ingenier铆a", "Ingl茅s", "Negocios y Emprendimiento", "Marketing Digital", "Habilidades Blandas", "Startups"]){
            console.error("That's not an accepted category")
        } else {
            this._category = newCategory;
        }
    }
}

const desarrolloWeb = new LearningPath({
    category: "Desarrollo e Ingenier铆a",
    name: "Escuela de desarrollo web",
    courses: ["Curso b谩sico de computaci贸n", "Curso de HTML Y CSS", "Curso de POO"]
})

si va mi c贸digo 馃槃

class Student {
constructor({
name,
email,
twitter = undefined,
instagram = undefined,
approvedCourses= [],
learningPaths= [],
}){
this.name=name;
this.email=email;
this.socialMedia= {
twitter,
instagram,
};
this.approvedCourses=approvedCourses;
this.learningPaths=learningPaths;
}
};

class LearningPaths {
constructor({name,courses=[]}){
this._name=name;
this.courses=courses;
}
get name(){
return this._name
}
set name(nuevoNombre){
if(nuevoNombre===鈥渃urso malo鈥){
console.error(鈥渨ey鈥o鈥)
}else{
this._name= nuevoNombre;
}
}
}

class Student3 {
    constructor({
        name,
        email,
        username,
        twitter = undefined,
        instagram = undefined,
        approvedCourses = [],
        learningPaths = [],
    }) {
        this.name = name;
        this.myEmail = email;
        this.username = username;
        this.socialMedia = {
            twitter,
            instagram,
        };
        this.approvedCourses = approvedCourses;
        this.learningPaths = learningPaths;
    }
    get email() {
        return this.myEmail;
    }
    set email(newEmail) {
        if(newEmail !== this.myEmail) {
            console.error("You cannot change the email")
        } else {
            this.myEmail = newEmail;
        }
    }
}

//Instance
const john = new Student3({
    name: "JuanDC",
    username: "Juarg14",
    email: "[email protected]",
    twitter: "juan51",
    learningPaths: webDevelopment,
});

john.email = "[email protected]";

La primera vez que vi esto fue leyendo la documentacion de Typescript, les admito que fue un concepto que se me dificulto mucho terminar de aprenderlo.

Pero tiene ventajas muy marcadas, no solo proteger con el encapsulamiento, sino tambien aplicar logica de programacion a atributos que queremos proteger.

Asi es como usaria los getters y setters sin la sintaxis de clases:

function prototipo(var1, var2){
    this._var1 = var1;
    this.var2 = var2;
    this.GetVar1 = function (){
        return this._var1;
    }
    this.SetVar1 = function (var1){
        this._var1 = var1;
    }
}

const prototipo1 = new prototipo(5,10);

y estos son los getters y setters que agregue al codigo:

//cursos
class Course {
    constructor({
        name,
        classes = [],
        test,
    }){
        this._name = name;
        this.classes = classes;
        this.test= test;
    }
    get name(){
        return this._name;
    }
    set name(name){
        if(name === "Nombre feo"){
            console.error("Wey... no");
        }else{
        this._name = name;
        }
    }
}
//clases
class clases{
    constructor({
        name,
    }){
        this._name = name;
    }
    get name(){
        return this._name;
    }
    set name(name){
        this._name = name;
    }
}
//tests
class tests{
    constructor({
        name,
        score = 0,
        passed = false,
    }){
        this._name = name;
        this._score = score;
        this._passed = passed;
    }
    get name(){
        return this._name;
    }
    set name(name){
        this._name = name;
    }
    get score(){
        return this._score;
    }
    set score(score){
        this._score = score;
    }
    get passed(){
        return this._passed;
    }
    set passed(score){
        if(score >= 90){
            this._passed = true;
        }
        else{
            this._passed = false;
        }
    }
}
//learningpaths
class LearningPath{
    constructor({
        name,
        courses = [],
        cursosAgregados = [],
        cursosEnProgreso = [],
        cursosAprobados = [],
    }){
        this._name = name;
        this.courses = courses;
        this.cursosAgregados = [];
        this.cursosAprobados = [];
        this.cursosEnProgreso = [];
    }
    get name(){
        return this._name;
    }
    set name(name){
        this._name = name;
    }
}

Getters y setters sin la sintaxis de clases puede ser asi?

const counter = (() => {
  let privateCounter = 0;
  function changeBy(val) {
    const id = crypto.randomUUID();
    return privateCounter +=  id +val;
  }

  return {
    increment: () => changeBy(1),
    decrement: () => changeBy(-1),
    value: () => privateCounter,
  }
});
const idi = counter().value();
const privateId = counter().increment();
const privateId2 = counter().decrement();
const privateId3 = counter().increment();
console.log(idi,privateId);
console.log(privateId3);
console.log(idi,privateId2);
// clase curso
class Course{
    constructor({
        name,
        classes = [],
    }){
        this._name = name;
        this.classes = classes;
    }

    get name(){
        return this._name;
    }

    set name(NuevoNombrecito){
        if(NuevoNombrecito === "Curso malito de programacion"){
            console.error("Web... NO!");
        }else{
            this._name = NuevoNombrecito;
        }
    }
}

//instancia de curso
const cursoProgBasica = new Course(
    {
        name : "Curso gratis de programacion basica"
});

const cursoVGS = new Course(
    {
        name : "Curso Introduccion a VGS"
});

const cursoVGS2 = new Course(
    {
        name : "Curso practico VGS"
});

const cursoDefinitivoHTML = new Course(
    {
        name : "Curso definitivo de HTML y CSS"
});

const cursoPracticoHTML = new Course({
    name : "Curso practico de HTML y CSS",
});
// clase ruta de aprendisaje
class LearningPaths{
    constructor({
        name,
        courses = []
    }){
        this.name = name;
        this.courses = courses;
    }
}

// instancias de  rutas de aprendisaje
const escuelaWeb = new LearningPaths({
    name: "Escuela de desarrollo web",
    courses : [
        cursoProgBasica,
        cursoDefinitivoHTML
    ]
});

const escuelaData = new LearningPaths({
    name: "Escuela de DataScience",
    courses: [
        cursoPracticoHTML,
        cursoDefinitivoHTML,
    ]
});

const escuelaVgs = new LearningPaths({
    name: "Escuela de Vgs",
    courses: [
        cursoVGS,
        cursoVGS2
    ]
});


// clase estudiante
class Student{
    constructor({
        name, 
        username,
        email,
        twitter = undefined,
        instagram = undefined,
        facebook = undefined,
        approvedCourses = [],
        learningPaths = []
    }){
        this.name = name; 
        this.username = username;
        this.email = email;
        this.socailMedia={
            twitter,
            instagram,
            facebook
        };
        this.approedCourses = approvedCourses;
        this.learningPaths = learningPaths;
    }
}   

// instancias de la clase estudiante
const victor = new Student({
    name : "Victor Hugo Cruz",
    username : "hugutiobody",
    email : "[email protected]",
    learningPaths : [
        escuelaWeb,
        escuelaData
    ]
});

const vanesa = new Student({
    name : "Vanesa Pozo",
    username : "vanesita024",
    email : "[email protected]",
    learningPaths : [
        escuelaVgs,
        escuelaData
    ]
});

const emanuel = new Student({
    name : "Emanuel Cruz Pozo",
    username : "emita",
    email : "[email protected]",
    twitter : "emitas_pro"
});

Me gusta esta forma de get y ser mas que la de java

Hola ac谩 dejo dos formas de resolverlo

function pruebaGetSet(name) {
this._name = name;
}
//Forma Uno
pruebaGetSet.prototype.defineGetter(鈥榥ame鈥, function() {return this._name;});
pruebaGetSet.prototype.defineSetter(鈥榥ame鈥, function(val) {this._name = val;});

//Forma Dos
pruebaGetSet.prototype = {
get name() {
return this._name;
},
set name(name){
this._name = name;
}
}

Es importante tener en cuenta el guion bajo que se agrega en el _name. Si ese guion bajo no se agrega, no va a funcionar鈥

Sintaxis Prototipos

let errorNames = [
    "El Curso es Malo",
    "Curso Malito de Programaci贸n",
    "Curso Dif铆cl de Programaci贸n",
    "Curso Imposible de Programaci贸n",
];

function SintaxisPrototype(value1, value2) {
    this._value1 = value1;
    this.value2 = value2;
}

SintaxisPrototype.prototype = {
    get value1(){
        return this._value1;
    },
    set value1(addNewName){
        if(addNewName === errorNames) {
            console.error("Tranquilizate Maquinola");
        } else {
            this._value1 = addNewName;
        }
    }
    
}

El operador de estricta igualdad === revisa si dos operandos son iguales y produce un resultado Booleano. A diferencia del operador de igualdad regular ==, el operador de estricta igualdad siempre considera que los operandos de distinto tipo de valor son diferentes y nunca similares.

console.log(1 === 1);
// expected output: true

console.log('hello' === 'hello');
// expected output: true

console.log('1' ===  1);
// expected output: false

console.log(0 === false);
// expected output: false

Mi c贸digo :3

class Estudiante{
constructor({name,age,correo,facebook,twitter,insta}){
    this._name=name;
    this._age=age;
    this._socialMedia={
        facebook,
        twitter,
        insta
    }
}

get name(){
    return this._name
}
set name(nuenoName){
    this._name=nuenoName;
}

get age(){
    return this._age
}
set age(nuenoAge){
    this._age=nuenoAge;
}
get socialMedia(){
    return this._socialMedia

}
set socialMedia(nueva){
    this._socialMedia=nueva;
}
};




const Pedrito=new Estudiante({name:"Pedro",age:20,facebook:"Pedro MM"})

Por ahora s贸lo he asignado getters y setters para las clases 鈥淟earningPaths鈥 en los atributos name y**_ category _** y para la clase 鈥淐lase鈥 en el atributo name.
En ambos casos defin铆 como condicional, por ahora, que no se puedan asignar valores vac铆os ni undefined.
El c贸digo es este:

Clase Clase

class Clase{
    constructor({
        name,
        instructor,
        level,
    }){
        this._name = name;
        this.instructor = instructor;
        this.level = level;
    }
    get name(){
        return this._name;
    }
    set name(nuevoNombre){  
        if(nuevoNombre === "" || typeof nuevoNombre === "undefined"){
            console.log("El nombre de la clase no es v谩lido o no ha sido asignado.")
        }
        else{
            this._name = nuevoNombre;
        }
    }
};

Clase LearningPaths:

class LearningPath{
    constructor({
        name,
        courses = [],
        coursesNumber,
        category,
        instructors = [],
        projects = [],
        blogPosts = [],
        blogPostsNumber,
    }){
    this._name = name;
    this.courses = courses;
    this.coursesNumber = coursesNumber;
    this._category = category;
    this.instructors = instructors;
    this.projects = projects;
    this.blogPosts = blogPosts;
    this.blogPostsNumber = blogPostsNumber;
    }

    get name(){
        return this._name;
    }
    set name(nuevoNombre){ 
        if(nuevoNombre === "" || typeof nuevoNombre === "undefined"){
            console.error("El nombre de curso no es v谩lido o no ha sido asignado.")
        }
        else{
            this._name = nuevoNombre;
        }
    }
    get category(){
        return this._category;
    }       
    set category(nuevaCategor铆a){
        if(nuevaCategor铆a === "" || typeof nuevaCategor铆a === "undefined"){
            console.error("Categor铆a no asignada o no v谩lida.")
        }
        else{
            this._category = nuevaCategor铆a;
        }
    }
}

Buen dia campeon鈥

class Student {
  constructor({
    name,
    age,
    nationality,
    email,
    twitter = undefined,
    instagram = undefined,
    facebook = undefined,
  }) {
    this._name = name;
    this._age = age;
    this.nationality = nationality;
    this.email = email;
    this._socialMedia = {
      twitter,
      instagram,
      facebook
    };
  }
  get name() {
    return this._name;
  }
  set name(newName) {
    this._name = newName;
  }

  get age() {
    return this._age;
  }
  set age(newAge) {
    this._age = newAge;
  }

  get socialMedia() {
    return this._socialMedia;
  }
  set socialMedia(newsocialMedia) {
    this._socialMedia= newsocialMedia;
  }
};

const user = new Student({
  name:"Katherine", 
  age: 25, 
  nationality: "US",
  twitter: "@katherine_miller",
  instagram: "@katherine_miller",
  email: "[email protected]",
});

.- user.socialMedia.twitter = undefine

Utilice setter and getter para hacer un filtro de nombres baneados

let bannedList = ['Elver Galarga', 'Adolf Hitler']
class Student {
    constructor({
        nombre, edad, twitter=undefined, facebook = undefined, instagram=undefined, cursosAprobados = [], learningPaths=[], email
    }){
    this._nombre = nombre
    this.edad = edad
    this.cursosAprobados = cursosAprobados
    this.learningPaths = learningPaths
    this.email = email
}

get nombre(){
    return this._nombre
}
set nombre(nuevoNombre){
    if (bannedList.includes(nuevoNombre)){
        console.error('wey... no, escoge un nombre apropiado')
    }
    else{
        this._nombre = nuevoNombre
    }

}
}

Tambien podemos usar el operador ternario para la condicion

  set name(nuevoNombre) {
    (nuevoNombre === 'Curso Programacion Basica') 
    ? this._name = nuevoNombre : console.error('No puedes hacer eso');
  }

Aca lo que hice fue condicionar para que no se cambie el nombre, ya que no podemos saber que nombre se inventara el usuario, claro existen mejores formas pero para tema de este curso, funciona bien.

One of the core concepts of OOP is encapsulation. An important part of encapsulation is that data (object properties) should not be directly accessed or modified from outside the object. To access or modify a property we would use a getter (access) or a setter (modify), which are specific methods we define in our class.

Como reto le agregue una clase a los cursos y a esa misma clase le agregue comentarios, luego dentro de los comentarios agregue aportes y preguntas, aqu铆 el c贸digo (se aceptan consejos para mejorar, muchas gracias):

<code>
class Coment {
    constructor ({
        text,
        img,
        link
    }) {
        this.text = text
        this.img = img
        this.link = link
    }
}

class Ask extends Coment {

}

const coment1 = new Coment ({
    text: 'Excelente clase!',
    img: 'url: www.imagenesDeCodigo.com',
    link: 'url:...'
})

const ask1 = new Ask ({
    text: 'Tengo una duda en el minuto 2:36',
})

class Class {
    constructor ({
        name,
        duration,
        coments = {
            aports: [],
            asks: []
        }
    }) {
        this.name = name
        this.duration = duration
        this.coments = coments
    }
}

const clasePoo = new Class ({
    name: '驴Qu茅 es la Programaci贸n Orientada a Objetos?',
    duration: '3 min',
    coments: {
        aports: [coment1],
        asks: [ask1]
    }
})

class Course {
    constructor({
        name,
        clases = [],
    }) {
        this._name = name
        this.clases = clases
    }

    get name() {
        return this._name
    }

    set name(nuevoNombre) {
        if (nuevoNombre === 'Curso Malo de Programaci贸n B谩sica') {
            console.error('Wey... no')
        } else {
            this._name = nuevoNombre
        }
    }
}

const cursoProgBasica = new Course ({
    name: 'Curso Gratis de Programaci贸n B谩sica',
    clases: [clasePoo]
})

const cursoDefinitivoHtml = new Course ({
    name: 'Curso definitivo de HTML y CSS',
    clases: [clasePoo]
})

const cursoPracticoHtml = new Course ({
    name: 'Curso Pr谩ctico de HTML y CSS',
    clases: [clasePoo]
})

class LearningPath {
    constructor({
        name,
        courses = []
    }){
        this.name = name
        this.courses = courses
    }
}

const escuelaWeb = new LearningPath ({
    name: 'Escuela de Desarrollo Web',
    courses: [
        cursoProgBasica,
        cursoDefinitivoHtml,
        cursoPracticoHtml
    ]
})

const escuelaData = new LearningPath ({
    name: 'Escuela de Data Science',
    courses: [
        'Programaci贸n B谩sica',
        'Curso de DataBusiness',
        'Curso de DataViz',
    ]
})

const escuelaVgs = new LearningPath ({
    name: 'Escuela de Videojuegos',
    courses: [
        'Programaci贸n B谩sica',
        'Curso de Unity',
        'Curso de Unreal',
    ]
})

class Student {
    constructor ({
        name,
        email,
        userName,
        twitter = undefined,
        instagram = undefined,
        facebook = undefined,
        approvedCourses = [],
        learningPaths = [],
    }) {
        this.name = name
        this.email = email
        this.userName = userName
        this.socialMedia = {
            twitter,
            instagram,
            facebook,
        }
        this.approvedCourses = approvedCourses
        this.learningPaths = learningPaths
    }
}

const oscar = new Student({
    name: 'Oscar Mtz',
    userName: 'oscarmtz',
    email: '[email protected]',
    twitter: 'oscaramtz',
    approvedCourses: 
    [escuelaWeb.courses[0],
     escuelaWeb.courses[1],
     escuelaWeb.courses[2]
    ],
    learningPaths: [escuelaWeb, escuelaData],
})

const salvador = new Student({
    name: 'Salvador',
    userName: 'Salvador Gzz',
    email: '[email protected]',
    twitter: 'salvador_gzz',
    approvedCourses:
    [escuelaData.courses[0],
     escuelaData.courses[1]
    ],
    learningPaths: [escuelaData, escuelaWeb],
}) 

Les comparto como hice, para que cuando alguien quiera modificar el nombre al curso le aparezca error

set name(nuevoNombrecito){
        if(nuevoNombrecito !== this.name){
            console.error("no puedes cambiar el nombre de el curso")
        }
        else{
            this._name = nuevoNombrecito;
        }
    }

La verdad me quedaron algunas dudas sobre los getters y setters pero con la documentaci贸n oficial pude entenderlo mejor, aqui les dejo los enlaces:

no se pero siento una gran aburrimiento con este curso鈥

Buena clase profe, pero no entend铆 muy bien qu茅 tienen que ver los setters y getters con el encapsulamiento. 馃槬

El cumpa se hace muchas bolas, ac谩 lo explican mejor: https://www.youtube.com/watch?v=iPw-5EOqh5Y

Getters y Setters

Son m茅todos de acceso que nos permiten traer los valores de cada uno de los atributos que tengamos de una clase y poder, establecer o modificarlos.

get: permite obtener los datos de una propiedad de la clase, para hacer una operaci贸n o mostrar en pantalla.

set: permite establecer o modificar datos si estos est谩n cargados.

Tuve problemas al utilizar m贸dulos para separar las clases en diferentes archivos. Luego de investigar un buen tiempo, encontr茅 la soluci贸n de window.

const FreddyVega = new Teacher({
  id: 1,
  name: 'Freddy Vega',
  speciality: 'CEO',
});
console.log(FreddyVega);

window.FreddyVega = FreddyVega;

Luego de crear la instancia la mandamos a window, de manera que en la consola ya podemos acceder a las propiedades con window as铆 (por ejemplo):

window.FreddyVega.speciality;

Dejo enlace que describe el cambio de convenci贸n (_) a uno usado directamente por Javascript para el manejo de atributos privados (#). 馃挍馃馃徎

馃敆 atributos-privados-clases-js

function Student({name, points = 0}){
    this._name = name;
    this._points = points;
}

Student.prototype = {
    constructor : Student,
    get name(){
        return this._name;
    },
    set name(newName){
        this._name = newName;
    }
}

Hay muchos compa帽eros que dicen usar la sintaxis del # para declarar las variables privadas, pero al acceder a un propiedad como normalmente lo har铆a me sigue devolviendo el valor, as铆 que tan segura no es 馃
.
.
Mi c贸digo:

	class Course{
    #name;
    #classes;

    constructor({name, classes = []}){
        this.#name = name;
        this.#classes = classes; 
    }

    get name(){
        return this.#name;
    }

    set name(newName){
        this.#name = newName;
    }

}

const cursoPrgmBasica = new Course({name: "Curso de programacion Basica"});

Les comparto un enlace para expandir el conocimiento de los Getters y Setters 馃槈

Como serian los setters y getters para los arrays y objetos?

驴Las clases van del lado del back end o front end?