Validación de Propiedades en Objetos JavaScript

Clase 16 de 20Curso Intermedio de Programación Orientada a Objetos en JavaScript

Contenido del curso

Resumen

Proteger la integridad de los datos es fundamental cuando construimos aplicaciones con objetos interconectados. En esta sesión se aplica duck typing para validar que los elementos agregados a una lista de rutas de aprendizaje realmente cumplan con las propiedades esperadas, todo dentro del proyecto Mini Platzi usando JavaScript puro.

¿Cómo crear una fábrica de objetos para learning paths?

Siguiendo el mismo patrón que createStudent, se construye una función llamada createLearningPath [01:00]. Esta función recibe un objeto con las propiedades necesarias: name (obligatorio) y courses (una lista de cursos). Internamente se crean dos objetos: uno privado y uno público.

El objeto privado almacena los valores reales de _name y _courses, mientras que el público expone getters y setters que controlan el acceso. Para name se reutiliza la misma lógica de validación que ya existía en los estudiantes: verificar que tenga cierta cantidad de caracteres antes de permitir la actualización.

¿Por qué courses solo tiene getter y no setter?

Una decisión de diseño importante aparece en [02:38]: los cursos no deben ser editables por cualquier usuario. Solo un estudiante de tipo profesor debería poder agregar cursos a una ruta de aprendizaje. Por eso se implementa únicamente un getter para courses, sin setter. Esto funciona como una capa de protección que limita la modificación directa de la lista de cursos desde fuera del objeto.

¿Cómo validar learning paths con duck typing antes de agregarlos?

Dentro de createStudent, la propiedad learningPaths también recibe getters y setters [03:48]. En el objeto privado se crea _learningPaths y desde el público se controla qué puede asignarse. La clave está en el setter: antes de agregar un nuevo learning path, se ejecutan varias validaciones encadenadas con ifs independientes (sin else if).

  • Primera validación: se comprueba si el nuevo elemento tiene la propiedad name. Si no la tiene, se muestra un console.warn y se detiene la ejecución con return [05:12].
  • Segunda validación: se verifica si tiene la propiedad courses. Sin ella, se lanza otra advertencia [06:20].
  • Tercera validación: se usa la función isArray para confirmar que courses sea efectivamente un array. Si es un string u otro tipo de dato, se rechaza [06:35].

Solo cuando las tres validaciones pasan, el nuevo learning path se agrega a la lista.

¿Por qué usar push en lugar de asignación directa?

Un error común aparece durante las pruebas [08:15]: al usar asignación directa (=), la propiedad _learningPaths deja de ser un array y se convierte en el objeto recibido. La solución es utilizar el método push para agregar el nuevo elemento sin reemplazar la lista completa.

javascript private._learningPaths.push(newLP);

Con este cambio, juan.learningPaths devuelve correctamente un array que contiene las rutas de aprendizaje añadidas.

¿Cuál es el problema de ser o tener en duck typing?

Aquí se revela la limitación central del duck typing [09:30]. Se puede agregar un objeto inventado manualmente que tenga name y courses como propiedades, y pasará todas las validaciones sin haber sido creado con createLearningPath. Esto significa que no se valida el origen del objeto, sino únicamente sus propiedades.

  • Un objeto creado con la fábrica createLearningPath hereda toda su lógica interna.
  • Un objeto literal con las mismas propiedades también pasa las validaciones.

Esto plantea la diferencia entre tener las propiedades correctas y ser realmente una instancia del tipo esperado. Las validaciones actuales solo responden a la pregunta "¿qué tiene?", pero no a "¿qué es?". Para resolver esto, el siguiente paso es trabajar con prototipos de JavaScript y así verificar la identidad real de cada elemento.

¿Has encontrado situaciones similares en tus proyectos donde necesites distinguir entre objetos que lucen igual pero tienen orígenes distintos? Comparte tu experiencia en los comentarios.