En mi ruta de aprendizaje personal si puedo agragar cursos. Jaque mate! B)
Introducción
¿Qué hay dentro de los objetos en JavaScript?
Profundicemos en los objetos
Static: atributos y métodos estáticos en JavaScript
Métodos estáticos del prototipo Object
Object.defineProperty
Cómo copiar objetos en JavaScript
Cómo funciona la memoria en JavaScript
Shallow copy en JavaScript
Qué es JSON.parse y JSON.stringify
Recursividad en JavaScript
Qué es recursividad
Deep copy con recursividad
Playgrounds: Hacer freeze de un objeto de forma recursiva
Abstracción y encapsulamiento sin prototipos
Factory pattern y RORO
Abstracción con objetos literales y deep copy
Module pattern y namespaces: propiedades privadas en JavaScript
Getters y setters
Cómo identificar objetos
Qué es duck typing
Duck typing en JavaScript
Instance Of en JavaScript con instancias y prototipos
Atributos y métodos privados en prototipos
Creando métodos estáticos en JavaScript
Próximos pasos
¿Quieres más cursos de POO en JavaScript?
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Juan David Castro Gallego
Vamos a definir cuáles son las propiedades que deben tener ciertos objetos para determinar cuál es cuál y así construir objetos más completos.
Vamos a validar que cuando generemos un nuevo estudiante, las rutas de aprendizajes tengan los datos necesarios para poder ser agregados en el array del atributo learningPaths
:
Creamos una función createLearningPath
para poder generar nuevas rutas de aprendizaje. Aquí validaremos que tenga los atributos necesarios:
function isObject(subject) {
return typeof subject == "object";
}
function isArray(subject) {
return Array.isArray(subject);
}
function requiredParam(param) {
throw new Error(param + " es obligatorio");
}
function createLearningPath({ // 👈👈
name = requiredParam("name"), // Campo obligatorio
courses = [], // Lista de Cursos que pertencen a la ruta de aprendizaje
}) {}
function createStudent({
name = requiredParam("name"),
email = requiredParam("email"),
age,
twitter,
instagram,
facebook,
approvedCourses = [],
learningPaths = [],
} = {}) {
const privateAtributos = {
"_name": name,
};
const publicAtributos = {
email,
age,
approvedCourses,
learningPaths,
socialMedia: {
twitter,
instagram,
facebook,
},
get name() {
return privateAtributos["_name"];
},
set name(newName) {
if (newName.length != 0) {
privateAtributos["_name"] = newName;
} else {
console.warn("Tu nombre debe tener al menos 1 caracter");
}
},
};
return publicAtributos;
}
Creamos 2 variables en las que dividiremos nuestras propiedades públicas y privadas:
function isObject(subject) {
return typeof subject == "object";
}
function isArray(subject) {
return Array.isArray(subject);
}
function requiredParam(param) {
throw new Error(param + " es obligatorio");
}
function createLearningPath({
name = requiredParam("name"), // Campo es obligatorio
courses = [], // Lista de Cursos que pertencen a la ruta de aprendizaje
}) {
const private = { // 👈👈 Atributos privados
"_name": name,
"_courses": courses,
};
const public = {}; // 👈👈
}
function createStudent({
name = requiredParam("name"),
email = requiredParam("email"),
age,
twitter,
instagram,
facebook,
approvedCourses = [],
learningPaths = [],
} = {}) {
const privateAtributos = {
"_name": name,
};
const publicAtributos = {
email,
age,
approvedCourses,
learningPaths,
socialMedia: {
twitter,
instagram,
facebook,
},
get name() {
return privateAtributos["_name"];
},
set name(newName) {
if (newName.length != 0) {
privateAtributos["_name"] = newName;
} else {
console.warn("Tu nombre debe tener al menos 1 caracter");
}
},
};
return publicAtributos;
}
En la variable public
definiremos los getters y setters para los atributos name
y courses
:
function isObject(subject) {
return typeof subject == "object";
}
function isArray(subject) {
return Array.isArray(subject);
}
function requiredParam(param) {
throw new Error(param + " es obligatorio");
}
function createLearningPath({
name = requiredParam("name"), // Campo es obligatorio
courses = [], // Lista de Cursos que pertencen a la ruta de aprendizaje
}) {
const private = { // Atributos privados
"_name": name,
"_courses": courses,
};
const public = { // 👈👈 Getters y Setters
get name() {
return private["_name"];
},
set name(newName) {
if (newName.length != 0) {
private["_name"] = newName;
} else {
console.warn("El nombre debe tener al menos 1 caracter");
}
},
get courses() {
return private["_courses"];
},
};
}
function createStudent({
name = requiredParam("name"),
email = requiredParam("email"),
age,
twitter,
instagram,
facebook,
approvedCourses = [],
learningPaths = [],
} = {}) {
const privateAtributos = {
"_name": name,
};
const publicAtributos = {
email,
age,
approvedCourses,
learningPaths,
socialMedia: {
twitter,
instagram,
facebook,
},
get name() {
return privateAtributos["_name"];
},
set name(newName) {
if (newName.length != 0) {
privateAtributos["_name"] = newName;
} else {
console.warn("Tu nombre debe tener al menos 1 caracter");
}
},
};
return publicAtributos;
}
En este caso no definimos un setter a courses, ya que
no cualquiera debería realizar asignaciones a ese atributo.
Ahora en la función createStudent
eliminamos el atributo learningPaths
de los atributos públicos y lo pasamos al objeto de atributos privados. Luego, generaremos el getter y setter respectivo:
function isObject(subject) {
return typeof subject == "object";
}
function isArray(subject) {
return Array.isArray(subject);
}
function requiredParam(param) {
throw new Error(param + " es obligatorio");
}
function createLearningPath({
name = requiredParam("name"), // Campo es obligatorio
courses = [], // Lista de Cursos que pertencen a la ruta de aprendizaje
}) {
const private = { // Atributos privados
"_name": name,
"_courses": courses,
};
const public = { // Getters y Setters
get name() {
return private["_name"];
},
set name(newName) {
if (newName.length != 0) {
private["_name"] = newName;
} else {
console.warn("El nombre debe tener al menos 1 caracter");
}
},
get courses() {
return private["_courses"];
},
};
}
function createStudent({
name = requiredParam("name"),
email = requiredParam("email"),
age,
twitter,
instagram,
facebook,
approvedCourses = [],
learningPaths = [],
} = {}) {
const privateAtributos = {
"_name": name,
"_learningPaths": learningPaths, // 👈👈
};
const publicAtributos = {
email,
age,
approvedCourses,
//learningPaths,👈👈
socialMedia: {
twitter,
instagram,
facebook,
},
get name() {
return privateAtributos["_name"];
},
set name(newName) {
if (newName.length != 0) {
privateAtributos["_name"] = newName;
} else {
console.warn("Tu nombre debe tener al menos 1 caracter");
}
},
get learningPaths() { // 👈👈
return private["__learningPaths"];
},
set learningPaths(newLP) { // 👈👈
// AQUÍ empezamos a aplicar DUCK TYPING 👀🦆
if (!newLP.name) {
// Si la nueva ruta de aprendizaje NO tiene el atributo "name"...
console.warn("Tu LP no tiene la propiedad name");
return; // Cortamos el proceso y no agregamos la ruta de aprendizaje
}
if (!newLP.courses) {
// Si la nueva ruta NO tiene asignado un array
// en el atributo "courses"
console.warn("Tu LP no tiene courses");
return; // Cortamos el proceso y no agregamos la ruta de aprendizaje
}
if (!isArray(newLP.courses)) {
// Si el atributo "courses" en la nueva ruta de aprendizaje NO es un Array
console.warn("Tu LP no es una lista (*de cursos)");
return; // Cortamos el proceso y no agregamos la ruta de aprendizaje
}
// Si la nueva ruta de aprendizaje pasó por todas las validaciones
// correctamente...Quiere decir que SÍ es una ruta válida tal como
// la deseamos que fuese. Por tanto, procedemos a añadir ese Learning Path
// a la lista de rutas del estudiante:
private["_learningPaths"].push(newLP);
},
};
return publicAtributos;
}
Ahora ya podríamos añadir nuevas rutas con los atributos que esperamos que tenga una ruta de aprendizaje a los nuevos estudiantes:
// NUEVO ESTUDIANTE:
const juan = createStudent({email:"[email protected]",name:"Juanito"});
// Le asignamos al estudiante "juan" un ruta de aprendizaje:
juan.learningPaths = {
name: "Escuela de Desarrollo Web",
courses: [],
}
En teoría, la ruta que añadimos es un learning path, sin embargo, no hemos validado que se haya generado esa ruta de aprendizaje con la función generadora de learning paths (createLearningPath
). Es decir, nosotros no creamos la ruta de “desarrollo web” de este modo:
const escuelaWeb = createLearningPath({
name: "Escuela de Desarrollo Web",
courses: []
})
Si no que lo hicimos directamente en el objeto juan
. El objeto escuelaWeb
es una ruta que heredó las propiedades de la función fábrica de learning paths y el otro es uno que producimos directamente desde el objeto juan
.
Lo anterior nos lleva al problema SER o TENER: no estamos validando si nuestros learning paths son realmente objetos que se construyeron desde createLearningPath
, lo que validamos es que sí tienen los atributos que esperaríamos que tenga una ruta de aprendizaje.
Comenzaremos a utilizar nuevamente prototipos de JavaScript para ahora sí validar qué objetos son realmente rutas de aprendizajes y no solo confirmar si tienen o no las propiedades que los convierte en un learning path. Aprendamos acerca de *instance of* en JavaScript. ¡Vamos a ello! 👨🚀🚀
Contribución creada por: Martín Álvarez (Platzi Contributor)
Aportes 35
Preguntas 12
En mi ruta de aprendizaje personal si puedo agragar cursos. Jaque mate! B)
Esta clase en especifico me parece que es la viva muestra de las dificultades que enfrenta la enseñanza del oficio de la programación a base de escribir código con las comodidades de una computadora.
Una pizarra tiene la posibilidad de aterrizar toda la abstracción que representan los paradigmas y sus soluciones, despues de que esto este aterrizado, ahi si hay que escribir codigo, ahí si hay que hacer la transferencia sintactica.
Ojala se den cuentra pronto de este grave problema en Platzi, tienen un trabajo fuerte que realizar en didactica.
Muy entendible todo, pero cada vez me gusta mas TS por lo mismo xd
La clase esta entendible pero hay q hacer un gran esfuerzo de parar muchas veces volver a verlo y apuntar el estado del codigo segun los min del video.
seria muy util ponerle un “indice de minutos” vs eventos (asi como se puede hacer en youtube … mas o menos asi) .
eso ayudaria bastante a brincar de un punto a otro mas rapido para ver bien que parte del codigo nos perdimos.
por que mucho scroll.
y esa mecanica serviria para toda la plataforma creo yo.
Viene pasando en muchos de los cursos de la ruta de Desarrollo Web, a veces el profesor tiene un ritmo de scroll bastante rápido y desorienta muchísimo. Ni siquiera viendo varias veces el vídeo logras centrarte. Es una pena.
Hay métodos mucho mejores para enseñar que scrollear todo el rato un código. Una lástima.
Me gusta la manera en la que nos introducimos en los getters y setters, es mucho más integral que en otros cursos =)
Se puede declarar una variable como privada asi #miVariable, con el # la volvemos privada y sha
Como recomendación, se debería mejorar en la metodología, eso de borrar código o editar código de anteriores clases confunde, se pierde mucho tiempo en tratar de entender un video, además se debería explicar el porque de cada paso q se realiza. Los cursos muy poco didácticos.
en algunos cursos siento que falta practicas de verdad, ósea en los cursos el profesor que lo este dando, explica todo y va haciendo algún ejercicio de ejemplo, pero si quiero practicar por mi cuenta no se donde podría aplicarlo en algo que sea útil y no solo escribir código sin sentido,
me gastaría que los ejemplos que pongan sean de algún problema que se vea en la vida real o se cree algún programa que solucione algo de verdad, alguna mini pagina que resuelva algún problema aplicando lo que se vea en las clases,
porque la mayoría de ejemplos que ponen, solo se hacen para que entendamos como funciona, pero no solucionan ningún problema, o es código que solo esta por estar, es como escribir la teoría
también me gastaría algún curso o una serie de cursos así sea exclusivo para expert , donde hagamos una pagina completa con todas sus funcionalidades, como si ya estuviéramos en una empresa o como FreeLancer y nos dijeran aquí están los diseños, crea esta pagina que consuma api que se conecte con el backend que tenga un login en fin que sea completa,
Hola! Me gusta mucho como explica el profe pero me gustaria profundizar mas en esta clase, asi sea con un ejemplo un poco mas sencillo! Creo que por lo que ya teniamos un codigo tan grande y toco borrar todos los commentarios y mover codigo de un lado a otro me perdi mucho 😦
Se trata de una estimación subjetiva de si el objeto es de un tipo u otro según las propiedades y métodos que lo compongan.
·
Sin embargo, en Javascript, puede ser una herramienta útil para determinar tanto el tipo de datos de un objeto concreto hasta para facilitar una pseudo implementación de interfaces cuando programamos en POO puro.
·─
Seria mas practico si se realiza con un proyecto real.
ya que en este curso para poder interpretrar en los proyecto que uno quiera aplicar se tendra muchas falencias.
Si quieren ver los apuntes de cada clase y el código numerado según se fue avanzando, pueden verlo aquí en mi GitHub 🚀
Hasta el momento vamos así…
Si están revisando los recursos de la clase se darán cuenta de que están todo desordenado, no se estresen con eso… Mejor vean la recopilación ordenada que está en mi GitHub 🚀
En resumen:
Todo fluye.
No puedo bañarme dos veces en el mismo río, pues yo no soy el mismo, y el río tampoco
Heráclito de Éfeso
Un poco dificil de enteder a la primera, pero luego se va aclarando poco a poco el contexto del ejercicio. Espero poder hacerlo individualmente en otro proyecto :¨)
Como critica constructiva, el scroll debería ser mas lento y explicarse un poco mejor a donde se está moviendo dentro del código. A partir del 4:10 me pierdo entre tantos scrolls rápidos.
👀 Fue bastante confusa esta clase por el scroll. Pero veamos si entendi: ¿Hay que hacer verificaciones de los valores recibidos en las propiedades? En este caso comprobar que el nombre de la ruta no este vacio y que se halla recibido un array.(?
Lo más importante en duck typing es el comportamiento de nuestro objeto es decir sus metodos, nos preocupamos solo por sus metodos y no por sus propiedades👀
jajaja la gente superficial no entenderá esta clase jjj, pero sí los que miran mas adentro
En el transcurso del video no entendía nada, pero luego al analizar el código ordenadito por fin entendí que hace cada cosa. ✌🙂🔥
import { is_array } from "./11.validation.mjs";
function error_detector(param) {
throw new Error(param + " es obligatorio");
}
function create_learning_path({
name = error_detector("name"),
courses = [],
} = {}) {
const new_private = {
_name: name,
_courses: courses,
};
const new_public = {
get name() {
return new_private._name;
},
// 👀👇 ale.name = 'zombie'
set name(new_name) {
if (new_name.length != 0) {
new_private._name = new_name;
} else {
console.log("Add a name!!!");
}
},
get courses() {
return new_private._courses;
},
};
return new_public;
}
function create_student({
name = error_detector("name"),
email = error_detector("email"),
age,
twitter,
instagram,
facebook,
approved_courses = [],
learning_paths = [],
} = {}) {
const new_private = {
_name: name,
_learning_paths: learning_paths,
};
const new_public = {
age,
email,
social_media: { twitter, instagram, facebook },
approved_courses,
get name() {
return new_private._name;
},
set name(new_name) {
if (new_name.length != 0) {
new_private._name = new_name;
} else {
console.log("Add a name!!!");
}
},
get learning_paths() {
return new_private._learning_paths;
},
set learning_paths(new_lpath) {
if (!new_lpath.name) {
console.log(
"Your learning path does not have the property name"
);
return;
}
if (!new_lpath.courses) {
console.log(
"Your learning path has no courses"
);
return;
}
if (!is_array(new_lpath.courses)) {
console.log(
"Your learning path is not a list (courses)"
);
return;
}
new_private._learning_paths.push(new_lpath);
},
};
return new_public;
}
const ale = create_student({
name: "Ale Roses",
age: 18,
email: "[email protected]",
twitter: "alerxses",
});
//ale.learning_paths = "New learning path";
ale;
// vemos get y sett para learning paths
ale.learning_paths;
// []
ale.learning_paths = "New school...";
// Menssage: Your learning path does not have the property name
ale.learning_paths = {
name: "New school - Test 02",
};
// Message: Your learning path has no courses
ale.learning_paths = {
name: "New school - Test 03",
courses: "Course one",
};
// Message: Your learning path is not a list (courses)
ale.learning_paths = {
name: "New school - Test 03",
courses: ["Course two"],
};
// Ahora sí
ale.learning_paths;
// [{name: "escuelas.."}]
// Prueba que también funciona
const school_insane = create_learning_path({
name: "insane insane",
courses: [],
});
ale.learning_paths = school_insane;
// Vemos que si añadio
ale.learning_paths;
console.log({ ale });
el curso es bueno y esta bien dado. Esta mal ordenado a la hora de mostrar el código, ya que al reutilizar código hace todo en el mismo archivo y termina teniendo un chorizo gigante de cosas que usa en un momento borra en otras y así. Lo cual al final para la relectura del estudiante a futuro lo deja muy enredado. Creo que debería tomar las propiedades de código que si usara, pegarlas en un nuevo archivo y ahí si mostrar lo que quiere hacer, para que quede mas ordenado y al final pegar todo en un solo main para la ejecución. Yo fui sacando pedazos de código de esa manera y lo note mucho mas legible. Este problema también se encuentra en el curso básico de POO de js y la verdad queda un main.js enorme y difícil de releer.
velocidad de video, todos poner su Playback Rate en 0.85x y no en 1x
Se olvido de decir learnignPath… 😒
“DesarroSHo web” bien argento jajajaja
Bueno, sentí que entendí esta clase, pero también me complique por el desorden del profe.
10:14 toca verificar que funcione la clase o factorypattern createStudent tras sus nuevos cambios en get y set learningPaths
function createLearningPaths empezo a exisir
ya pego los get y set en createLearningPaths(){..... public={ por aca dentro }}
Borro setter de Courses en createLearningPaths()
crea dentro de createStudent los metodos get y set para la propiedad learningPaths ojo dentro de
Validando el parametro learningPaths en el set learningPaths dentro de createStudent
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?