exportclassCourse{constructor({ name, classes =[],}){this._name='';// Inicializa la propiedad privada _name como una cadena vacíathis.name= name;// Llama al setter de name para validar y actualizar el valor de _namethis.classes= classes;// Inicializa la propiedad classes con un valor opcional}getname(){returnthis._name;// Devuelve el valor actual de _name}setname(newName){if(typeof newName ==='string'){// Comprueba si newName es un string válido newName = newName.trim();// Elimina los espacios en blanco al inicio y al final del stringif(newName !==''){// Comprueba si el string resultante no es vacíothis._name= newName
.split(' ')// Divide el string en palabras usando un espacio como separador.map((word)=> word.charAt(0).toUpperCase()+ word.slice(1))// Convierte la primera letra de cada palabra en mayúsculas.join(' ');// Vuelve a unir las palabras en un string usando un espacio como separador}}// Si newName no es un string válido o es un string vacío, no se modifica el valor de _name}}
Muy útil tu aporte
Gracias
Mi solución, aunque en acá no corre, en Visual Studio Code sí me funcionó :D
exportclassCourse{constructor({ name, classes =[],}){this._name= name;this.classes= classes;}getname(){returnthis._name;}setname(nuevoNombrecito){if(typeof nuevoNombrecito !=="string"){console.log("Parce no puedes hacer eso");}else{this._name= nuevoNombrecito[0].toUpperCase()+ nuevoNombrecito.slice(1);}}}
Coincidí con tu solución y tampoco me corre.
No estas creando el nuevo objeto del prototipo (Clase) Course
const courseName ="curso de programación básica"const nombreMaysuculas =newCourse({name: courseName,})nombreMayusculas.name
Casi no lo entiendo pero de a poco lo fui solucionando.
constructor({
name,
classes = [],
}) {
this.name = name;
this.classes = classes;
}
get name() {
return this._name;
}
set name(nuevoNombrecito) {
if (typeof nuevoNombrecito === "string") {
nuevoNombrecito = nuevoNombrecito.trim()
if (nuevoNombrecito.length !== 0) {
let words = nuevoNombrecito.split(" ")
let nuevoNombrecitoMayusculas = words.map((word) => {
if (word.length > 0) return `${word[0].toUpperCase()}${word.slice(1)}`;
}).join(" ")
this._name = nuevoNombrecitoMayusculas
}
}
}
}
Excelente, me ayudó a ver por que no aceptaba el mio. No tomé en cuenta dobles espacios. Gracias por compartir.
He intentado muchas combinaciones diferentes y aunque en mi VSCode funciona y en la consola del explorador funciona, este playground continua diciendo que tiene fallas. Utilice el codigo de varios compañeros. Hice combinaciones con forEach, ciclos for, map y en todas las ocaciones sigue diciendo que el resultado es erroneo, a pesar que como mencione, en las consolas del explorador y en la de VSC funciona a la perfeccion.
Creo que el error es porque por debajo el PlayGround toma el valor de la variable llamada name y no _name. Para que funcione correctamente, la variable debe llamarse _name o si no, existe un error de llamado, ya que el lenguaje ve un desbordamiento al tener tanto la propiedad name como la función set name. Creería que ese es el error porque a mi también me sucede exactamente lo mismo.
Yo lo he estaba probando siempre en la pestaña Vista y siempre me daba error RangeError: Maximum call stack size exceeded: y cuando abrí la consola hacia lo que debía hacer cuando usaba el console.log, ejecute las pruebas y paso.
Aunque fue un poco diferente a la solucion mi codigo lo realice de la siguiente manera
exportclassCourse{constructor({ name, classes =[],}){this._name= name;this.classes= classes;}getname(){// Tu código aquí 👈returnthis._name;}setname(nuevoNombrecito){// Tu código aquí 👈if(typeof nuevoNombrecito ==="string"){const newName = nuevoNombrecito
const palabras = newName.split(" ");const word = palabras.map((palabra)=>{return palabra[0].toUpperCase()+ palabra.substring(1);}).join(" ")// console.log(palabras);console.log(word);this._name= word;}else{console.error("no se puede cambiar el nombre")}}}const courseName ="curso de programación básica";const nombreMaysuculas =newCourse({name: courseName,})nombreMaysuculas.name= courseName;
Mientras pases las pruebas la solución es válida para el reto, casi siempre hay más de una manera de hacer las cosas, felicidades! 🥳
Segun el playground tu codigo tampoco funciona, pero en el explorador y en la VSC si funciona.
this.name = name; vs this._name = name; 😱🤔
En el constructor al usar this._name = name; no se aplica el set a la primera instancia creada, solo se aplica a las siguientes, pero al usar this.name = name; si se aplica desde la primera instancia.
La razón por la que la primera instancia de la clase Course creada no se beneficia de la validación en el método setter cuando se utiliza this._name = name; en el constructor, es porque el método setter solo se invoca cuando se establece el valor de la propiedad name después de la creación del objeto. En el constructor, se está estableciendo directamente el valor de la propiedad privada _name sin pasar por el método setter.
Por otro lado, cuando se utiliza this.name = name; en el constructor, se está llamando al método setter directamente, y, por lo tanto, se aplica la validación en el valor de name incluso en la primera instancia creada.
Por ejemplo, si se crea una instancia de la clase Course utilizando this._name = name; en el constructor:
En este caso, como se ha establecido directamente el valor de la propiedad privada _name en el constructor, la validación en el método setter no se ha aplicado, y, por lo tanto, el valor de name sigue siendo "course one".
Por otro lado, si se crea una instancia de la clase Course utilizando this.name = name; en el constructor:
En este caso, al utilizar this.name = name; en el constructor, se llama al método setter directamente y se aplica la validación en el valor de name, por lo que el valor de name se cambia a "Course One" (con la primera letra de cada palabra en mayúscula).
Es importante tener en cuenta que, aunque el método setter no se llama al establecer directamente el valor de la propiedad privada _name en el constructor, el método getter sí se puede utilizar para acceder al valor de la propiedad _name desde fuera de la clase.
Nota Importante: Yo lo he estaba probando siempre en la pestaña Vista y siempre me daba error RangeError: Maximum call stack size exceeded: y cuando abrí la consola hacia lo que debía hacer cuando usaba el console.log, ejecute las pruebas y funciono.
exportclassCourse{constructor({ name, classes =[]}){this.name= name;this.classes= classes;}getname(){// Tu código aquí 👈returnthis.name;}setname(nuevoNombrecito){// Tu código aquí 👈if(typeof nuevoNombrecito ==="string"){ nuevoNombrecito = nuevoNombrecito.trim();if(nuevoNombrecito.length!==0){let words =[]; nuevoNombrecito.split(" ").forEach(function(word){ words.push(word[0].toUpperCase()+ word.substring(1));});this._name= words.join(" ");}else{console.log("Solo tiene permitido string");}}}}
Para probar que funcionara bien debajo de este bloque de código agregue este para revisar en la consola
const courseName ="curso de programación básica 1";const nombreMayusculas =newCourse({name: courseName,})nombreMayusculas.name="curso de programación básica 2";
Y agregue en la clase Course un
console.log(this._name)
después de la línea de código esta
this._name= words.join(" ");
A pesar de error antes comentado que me muestra en la consola si muestre bien el cambio por eso ejecute las pruebas.
Alerta spoiler, aqui va mi solucion:
classCourse{constructor({ name, classes =[]}){this._name= name
this.classes= classes
}getname(){returnthis._name}setname(nuevoNombrecito){// tipo stringif(typeof nuevoNombrecito !=="string"){console.error("debe ser string")}elsethis._name= nuevoNombrecito[0].toUpperCase()+ nuevoNombrecito.slice(1)}}
aun te falta usar el metodo new para verificar que funcione
Les dejo mi aporte, espero le sirva a alguien en el futuro :)
Dos cosas a agregar. El ejercicio tiene un typo a la hora de querer ejecutar la clase.
Segundo, el concepto no queda claro. Yo usaba el nombre de la propiedad ("name") igual en todo lado para acceder a ella y eso me generaba un ciclo infinito que no entiendo el por que.
Veo que la solución es agregar _name para el getter y setter para evitar el loop ya que javascript lo toma como la variable privada.
El ejemplo no me parece correcto para entender el concepto ya que el getter y setter puede tener otro nombre y así funcionar el codigo. Tal como está planteado no se lográ solucionar con lo que se enseña..
Por lo que logre entender, después de una larga búsqueda de definiciones y ejemplos. Me parece que el error ocurre cuando manejas todo con name. Esto debido a que la palabra reservada set como dice la documentación oficial: asocia la propiedad de un objeto a una función que será llamada cuando haya un intento de asignar valor a esa propiedad.
Utilicemos el siguiente código:
classCourse{constructor({ name, classes =[]}){this.name= name;this.classes= classes;}getname(){returnthis.name;}setname(nuevoNombrecito){this.name= nuevoNombrecito;}}const cursoUno =newCourse({name:"Cursito"});cursoUno.name="Cursito de programación";// RangeError: Maximum call stack size exceeded
Como vemos es una clase muy básica pero el problema radica en el nombre de la propiedad del objeto o en el nombre del método setter ya que estamos diciendo que:
Cuando asignemos un nuevo nombre a la propiedad name estamos llamando al setter, pero el mismo setter dentro de su lógica tiene la misma sintaxis que utilizamos para asignar el nuevo nombre, por lo que vuelve a llamar al setter y entra en un bucle infinito donde el setter se esta llamando a sí mismo.
¿Cómo corregirlo?
Tendríamos que cambiar el nombre de la propiedad a this._name o cambiar el nombre del método set a newName(nuevoNombrecito). Aunque la segunda opción es valida, no pasarían las pruebas del ejercicio.
Se que es un poco larga la explicación pero espero les ayude a entender el porque del error.
Pueden ver que en el constructor no use el guión bajo (_) para nombrar la variable
this.name, pero en el get y set pueden ver que use this._name, cosa que al correr la prueba salió todo en verde, mientras que si usaba en todo this.name no funcioba. THIS IS WEIRD!
Lo de manejar el constructor sin guion y la asignación con guion no pensaba que fuera posible. Pero referente a lo otro es que si manejas todo con name tanto la propiedad como el set cuando intentas hacer la asignación internamente el setter se esta llamando a sí mismo
Mi solución......este si corre en ambos lados en el vsc y acá.....
functioncambioMayusculas(nuevoNombrecito){if(typeof(nuevoNombrecito)==="string"&& nuevoNombrecito.length!==0){const cambio=nuevoNombrecito.split(' ');const cambio2=cambio.map(item=>item.charAt(0).toUpperCase()+item.slice(1));const cambio3=cambio2.join(' ');return cambio3;}else{console.warn('el nuevo nombre no es un tipo de dato String ...')}}classCourse{constructor({name,classes =[],}){this._name=cambioMayusculas(name);this.classes= classes;}getname(){returnthis._name;}setname(nuevoNombrecito){if(typeof nuevoNombrecito==="string"&& nuevoNombrecito.length!==0){const cambio = nuevoNombrecito.trim();const cambio1=cambio.split(' ');const cambio2=cambio1.map(item=>item.charAt(0).toUpperCase()+item.slice(1));const cambio3=cambio2.join(' ');this._name=cambio3;}else{console.warn('el nuevo nombre no es un tipo de dato String ...')}}}const curso1 =newCourse({name:'curso de programación básica',})console.log(curso1.name);curso1.name="";console.log(curso1.name.length);
Me pasa todos las pruebas menos esta:
Alguien sabe por que ?, segun yo ya esta mitigada la parte de string vacio. Agradezco la retroalimentacion. 😁
Mi solución
classCourse{constructor({ name, classes =[]}){this._name= name;this.classes= classes;}getname(){// Tu código aquí 👈returnthis._name;}setname(nuevoNombrecito){// Tu código aquí 👈if(typeof nuevoNombrecito =="string"){const words = nuevoNombrecito.split(" ");for(let i =0; i < words.length; i++){ words[i]= words[i][0].toUpperCase()+ words[i].substring(1);}this._name= words.join(" ");}}}const courseName ="curso de programación básica";const nombreMaysuculas =newCourse({name: courseName,});nombreMaysuculas.name= courseName;console.log(nombreMaysuculas.name);