Freecodecamp: [beta] Sección de control de calidad de la programación orientada a objetos

Creado en 30 ene. 2017  ·  44Comentarios  ·  Fuente: freeCodeCamp/freeCodeCamp

Esto se abrió originalmente para un desafío específico, pero noté un par de otras cosas en el camino en esta sección, por lo que solo las consolidaré en este número (un comentario para cada uno). @HKuz , si tal vez ya haya otro problema para esto, supongo que usted será el que lo sepa, hice una búsqueda rápida pero no pude encontrar nada.

En general, creo que estos desafíos son geniales. _ ¡¡¡ Definitivamente _ una gran mejora sobre la sección de OOP existente !!!! ¡¡Enhorabuena a quien los creó !!

Comentarios / problemas generales:

  • Parece que en esta sección, una vez que hayas resuelto un desafío, puedes cambiar o incluso borrar el código, y el desafío seguirá siendo válido. Creé un problema separado para esto: # 13021
  • Sería bueno que los resultados se registren en la consola de desafío integrada para que las personas puedan ver los resultados de su código. A menudo llamamos métodos que registran cosas en la consola en estos desafíos, pero no están diseñados para iniciar sesión en la consola de la página.

Comentario más útil

Utilice la herencia para que no se repita :

Este desafío creo que es un poco confuso. El título se refiere a la herencia, sin embargo, la herencia nunca se menciona en el desafío; me doy cuenta de que se relaciona con el próximo desafío, por lo que los campistas lo descubrirán rápidamente, pero la forma en que se presenta sigue siendo un poco desagradable. Además, al final del desafío, hemos creado un Animal , pero nos quedamos un poco confundidos, porque Animal , en este punto, no se relaciona con Cat y Dog . Para calmar un poco la confusión, creo que podríamos hacer un pequeño cambio:

Esta frase proviene del próximo desafío:

Este y el próximo desafío cubrirá cómo reutilizar los métodos de Animal dentro de Bird and Dog sin definirlos nuevamente. Utiliza una técnica llamada herencia.

Quizás, para vincular las cosas, se puede dar una descripción general de nivel superior similar a esta en este desafío que une los 3 para que se entienda que son una secuencia, y en realidad introduce el concepto de que el desafío se titula después, y lo hace Claro que al final de este desafío aún no hemos terminado.

Todos 44 comentarios

Utilice la notación de puntos para acceder a las propiedades de un objeto

(RESUELTO EN ETAPAS) ✅

Este desafío solo acepta lo siguiente como solución:

console.log(dog.name);
console.log(dog.numLegs);

Sin embargo, no declaramos explícitamente que se deben usar 2 declaraciones separadas y lo siguiente no pasa:

console.log(dog.name, dog.numLegs);

Estoy pensando que deberíamos especificar que se deben realizar 2 declaraciones console.log() separadas o refactorizar la prueba para aceptar ambas soluciones; creo que preferiría la última opción. Pensamientos

Verifique el constructor de un objeto con instanceof :

(RESUELTO EN ETAPAS) ✅

  • Por alguna razón, el linter arroja la advertencia Expected an assignment of function call and instead saw an expression cuando se escribe la solución correcta myHouse instanceof House; . Sin embargo, el desafío pasa.
  • Además, el código semilla en sí tiene una advertencia de linter en la carga para un punto y coma faltante.
  • Por último, en este caso, no estoy seguro de si es intencional, pero puede ser un poco confuso; en desafíos anteriores en esta sección, los constructores se definen así:
function House(numBedrooms) {
  this.numBedrooms = numBedrooms;
}

pero en este desafío cambian a esta sintaxis:

let House = function(numBedrooms) {
  this.numBedrooms = numBedrooms;
}

Esto no es tanto un problema como una posible fuente de confusión. Si usamos ambas formas, creo que deberíamos notar específicamente la diferencia; de lo contrario, simplemente mantenga la sintaxis consistente en toda la sección. Probablemente presentar ambos es una buena idea, aunque creo.

Comprensión de las propiedades propias :

Solo una observación sobre este, y curiosidad por ver qué otras opiniones son, pero este desafío parece girar un poco más en torno a for...in lugar de hasOwnProperty , y for...in no explicado adecuadamente en esta sección hasta el momento.

Si asumimos que las personas han trabajado en el resto del plan de estudios, creo que esto está bien, porque esto está al menos cubierto en la sección Estructuras de datos básicas, pero si pretendemos que las secciones sean independientes entre sí y no requieran requisitos previos, es posible que deseemos volver a visitar esto?

Comprender la propiedad del constructor :

(RESUELTO EN ETAPAS) ✅

Este desafío pasará con cualquiera de las soluciones:

function joinDogFraternity(candidate) {
  if (candidate instanceof Dog) {
    return true;
  }
  return false;
}

// OR:

function joinDogFraternity(candidate) {
  if (candidate.constructor === Dog) {
    return true;
  }
  return false;
}

No veo que esto sea un problema importante, ya que el instinto dicta que la gente probará primero la solución que se les sugiera, sin embargo, también puedo ver que esto es un problema que se abrirá en el futuro cuando un campista inteligente intenta en ambos sentidos y quiere señale esto.

Podríamos simplemente agregar un caso de prueba que diga "message: 'your solution should use the constructor property'" y verificar con una expresión regular.

Utilice la herencia para que no se repita :

Este desafío creo que es un poco confuso. El título se refiere a la herencia, sin embargo, la herencia nunca se menciona en el desafío; me doy cuenta de que se relaciona con el próximo desafío, por lo que los campistas lo descubrirán rápidamente, pero la forma en que se presenta sigue siendo un poco desagradable. Además, al final del desafío, hemos creado un Animal , pero nos quedamos un poco confundidos, porque Animal , en este punto, no se relaciona con Cat y Dog . Para calmar un poco la confusión, creo que podríamos hacer un pequeño cambio:

Esta frase proviene del próximo desafío:

Este y el próximo desafío cubrirá cómo reutilizar los métodos de Animal dentro de Bird and Dog sin definirlos nuevamente. Utiliza una técnica llamada herencia.

Quizás, para vincular las cosas, se puede dar una descripción general de nivel superior similar a esta en este desafío que une los 3 para que se entienda que son una secuencia, y en realidad introduce el concepto de que el desafío se titula después, y lo hace Claro que al final de este desafío aún no hemos terminado.

Heredar comportamientos de un supertipo :

(RESUELTO EN ETAPAS) ✅

Problema súper menor aquí: parte de la semilla para esto dice lo siguiente:

// Add your code below this line

let duck
let beagle

duck.eat(); // Should print "nom nom nom"
beagle.eat(); // Should print "nom nom nom"

Esto arroja un error de linter. En su lugar, propondría lo siguiente:

Problema súper menor aquí: parte de la semilla para esto dice lo siguiente:


let duck; // change this line
let beagle; // change this line

duck.eat(); // Should print "nom nom nom"
beagle.eat(); // Should print "nom nom nom"

@ no-stack-dub-sack: todos estos son puntos geniales y no he visto ningún problema para esta sección, aunque ayer estuve desconectado una parte del día. Gracias por leer esta sección con tanto detalle 👍 Aquí están mis pensamientos (tl; dr - estoy de acuerdo con todo lo que mencionaste):

  • Use Dot Notation to Access the Properties of an Object : las pruebas deben aprobarse si alguien usa una instrucción console.log .
  • Verify an Object's Constructor with instanceof : debemos corregir el punto y coma que falta y ser coherentes con la forma en que se define House . Si bien hay varias formas de hacer las cosas en JS, no es necesario confundir a las personas que aprenden esto por primera vez.
  • Understanding Own Properties : En cuanto a su punto sobre for...in , generalmente consideramos que está bien usar conceptos ya cubiertos en el plan de estudios. Los campistas pueden saltar como quieran, pero hay un flujo de temas. (De lo contrario, los desafíos pueden volverse largos / repetitivos si tienen que volver a cubrir las cosas antes de llegar al grano). Dicho esto, creo que puede ser útil poner una nota justo debajo del ejemplo que explique brevemente la sintaxis ("Recuerde que for...in hace ...)
  • Understand the Constructor Property : acepte su punto para agregar usando el constructor en las instrucciones
  • Use Inheritance So You Don't Repeat Yourself : sí, buenos puntos para unir mejor los desafíos
  • Inherit Behaviors from a Supertype : definitivamente deberíamos agregar el punto y coma, y ​​los comentarios también son útiles

Avísame si quieres trabajar en esto: voy a pasar a otra sección (podría trabajar en esto en uno o dos días), o podríamos abrir esto si se necesita ayuda 😄

@HKuz ¡ Genial, gracias! Voy a terminar la sección, agregar algunos comentarios más si tengo alguno, y luego podemos decidir en ese momento, pero creo que abrirlo a Help Wanted probablemente sea lo mejor. Te mantendré informado.

Agregar métodos después de la herencia :

Este desafío es un poco confuso debido al siguiente caso de prueba:

Dog should have the bark() method as an own property.

La solución para esta parte busca esto:

Dog.prototype.bark = function() {
    console.log('Woof!');
};

y aunque Dog.prototype.hasOwnProperty('bark') devuelve true (así que esto es, por supuesto, correcto), la fuente de la confusión proviene de aquí (que es de Iterar sobre todas las propiedades ):
image

Con la información que se les da a los campistas hasta este punto, es probable que asuman que para aprobar esa prueba, tendrían que definir el método bark , directamente en la instancia del objeto Dog lugar de en el prototipo.

La distinción es que para instancias de Dog , bark _no_ sería una propiedad own , pero que _es_ una propiedad own de Dog.prototype . Por lo tanto, esto es un poco confuso para alguien que acaba de conocer estos conceptos.

La solución más simple sería cambiar el caso de prueba para decir:

Dog.prototype should have the bark() method as an own property.

Aunque, tal vez una explicación rápida sea para que los campistas sepan que una propiedad prototype de un prototipo es en realidad una propiedad own de ese prototipo. Vaya, eso es un trabalenguas, así que sí, es un poco confuso, y no estoy seguro de cuál es la mejor manera de disipar esa confusión ...

Utilice el cierre para evitar que las propiedades dentro de un objeto se modifiquen externamente :

(RESUELTO EN ETAPAS) ✅

Pequeño error tipográfico:

image

Creo que se supone que está "... fuera de la definición de bird ". ?

Comprender la expresión de función inmediatamente invocada (IIFE) :

No hay problemas importantes con este desafío, solo una sugerencia, aunque me doy cuenta de que los IIFE anónimos son el patrón más común (y el patrón que se usa en el próximo desafío), tal vez este sea un buen lugar para mencionar que IIFE también se pueden nombrar, y esto incluso podría considerarse una mejor práctica (aunque se ve con menos frecuencia) porque puede facilitar la depuración ya que los errores serán más difíciles de rastrear si hay muchos IIFE anónimos

Pensamientos

Utilice un IIFE para crear un módulo :

Me gustaría tener algunas ideas sobre este ... ¿tal vez @dhcodes o @Greenheart?
Mi problema es que no creo que el desafío explique adecuadamente por qué un IIFE tiene sentido en este escenario.

La solución requiere:

let funModule = (function() {
  return {
    isCuteMixin: function(obj) {
      obj.isCute = function() {
        return true;
      };
    },  
    singMixin: function(obj) {
      obj.sing = function() {
        console.log("Singing to an awesome tune");
      };
    }
  };
})();

para que puedas hacer algo como:

function Bird () { }
let duck = new Bird();
funModule.singMixin(duck);
duck.sing();

sin embargo, podría lograr lo mismo de una manera menos detallada y sin invocar una función en absoluto, simplemente definiendo el objeto que devuelve IIFE .

El desafío dice esto:

La ventaja del patrón de módulo es que todos los comportamientos de movimiento se pueden empaquetar en un solo objeto que luego puede ser utilizado por otras partes de su código.

Pero dado que esto no requiere un IIFE en absoluto, supongo que cuestionaría la idea de introducir el concepto aquí, o de encontrar una forma más sólida de vincularlo. Esto podría ser confuso / engañoso porque los campistas podrían pensar que NECESITAN hacer esto para lograr este patrón cuando ese no sea el caso.

¿Alguna idea?

@ no-stack-dub-sack Estoy de acuerdo en que este no es el mejor ejemplo de un IIFE. ¿Sería mejor si proporcionáramos un module como ejemplo?

Creo que el valor central del IIFE es que puede crear propiedades y métodos privados de sus objetos. Es realmente útil para disminuir las formas en que otros pueden (mal) usar su software con la esperanza de que haga las cosas más confiables.

Por ejemplo, es posible que tenga un pequeño módulo de utilidad para su aplicación vanilla js donde solo desea exponer algunos métodos públicos, ya que el resto está a punto de cambiarse / eliminarse y causaría problemas si se usaran en otras partes del código base.

Este sitio tiene muchos buenos ejemplos: https://toddmotto.com/mastering-the-module-pattern/

@Greenheart Bueno, en el último de los 2 desafíos de IIFE aquí, se presenta como un patrón de módulo, y no tengo ningún problema con eso, solo creo que podría explicarse más claramente _por qué_ usar un IIFE y que un IIFE no necesariamente tiene que estar presente para lograr la misma funcionalidad. Creo que esto lo dice todo:

El valor central del IIFE es que puede crear propiedades privadas y métodos de sus objetos. Es realmente útil para disminuir las formas en que otros pueden (mal) usar su software con la esperanza de que haga las cosas más confiables.

Si podemos explicar esto y hacerle saber al usuario "puede lograr la misma funcionalidad sin un IIFE, pero con un IIFE es una mejor manera, y aquí está el por qué ...".

Las instrucciones actuales dicen:

Una expresión de función invocada inmediatamente (IIFE) se usa a menudo para agrupar funciones relacionadas en un solo objeto o módulo.

A esto, agreguemos: "Si bien se puede lograr la misma funcionalidad sin un IIFE, el valor principal del IIFE, en este contexto, es que puede crear propiedades privadas y métodos de sus objetos. Esto puede ser muy útil para disminuir el formas en las que otros pueden (mal) usar su software y hacer que las cosas sean mucho más confiables ".

@ no-stack-dub-sack ¡Esto! :Hacer hincapié:

Tomé la libertad de compilarlo y hacer algunos cambios menores. Algo como esto es lo que necesitamos: rubor:
An <dfn>immediately invoked function expression</dfn> (IIFE) is often used to group related functionality into a single object or module. While the same functionality can be achieved without an IIFE, its core value in this context is that you can create private properties and methods for your objects. This can be very useful for decreasing the ways others can (mis)use your software, and make things much more reliable.

Posiblemente use <dfn> si el término no se ha usado en desafíos anteriores.

¡Continuaré y actualizaré las pruebas para Usar notación de puntos para acceder a las propiedades de un objeto !

Continuando con https://github.com/freeCodeCamp/freeCodeCamp/issues/12966#issuecomment -275974706.

El primer problema es porque el linter no quiere que escribamos una expresión que esencialmente sea código muerto (ya que ni llamamos a una función ni creamos una variable). Para solucionar esto, sugiero que asignemos el resultado a una variable.

El segundo y tercer problema podrían solucionarse cambiando la semilla para usar el código que propuso. La asignación de objetos de función a variables se puede enseñar en otro lugar o por experiencia. Creo que deberíamos ser coherentes con function X () {}

Arreglaré esto: sonríe:

Noté que ningún desafío tiene soluciones, así que actualmente estoy trabajando en un PR.

Comprensión de las propiedades propias :

(RESUELTO EN ETAPAS) ✅

Las pruebas actualmente permiten el uso del método integrado Object.keys() , pero creo que los campistas obtienen una mejor práctica al usar for...in combinado con Object.hasOwnProperty() .

Programación orientada a objetos: iterar sobre todas las propiedades :

(RESUELTO EN ETAPAS) ✅

Acabo de descubrir que este desafío tiene el mismo problema: permite el uso de Object.keys() Como todavía no creo que esto deba permitirse en estos desafíos, crearé un PR agregando el caso de prueba de esta línea

function Dog(name) {
  this.name = name;
}

Dog.prototype.numLegs = 4;

let beagle = new Dog("Snoopy");

let ownProps = Object.keys(beagle);
let prototypeProps = Object.keys(Dog.prototype);

Arreglando esto de inmediato: sonrisa:

Programación orientada a objetos: cambie el prototipo a un nuevo objeto

Instrucciones y pruebas insuficientes. ¿Deberían describe y eat existir en el prototype , o deberían ser funciones?

Creo que deberíamos agregar pruebas para verificar que son funciones.

Programación orientada a objetos: recuerde establecer la propiedad del constructor al cambiar el prototipo

PR enviado: white_check_mark:

Este desafío probablemente debería formatear la "propiedad del constructor" como <code>constructor</code> property para aumentar la legibilidad y la coherencia. ¿Qué piensas?

Por ejemplo, el mensaje de prueba usa este formato.

Una sugerencia general es que reemplacemos las declaraciones let con const para mostrar las mejores prácticas. ¡Este video de @mpj lo explica bien!

Programación orientada a objetos: restablecer una propiedad de constructor heredada :

PR enviado: white_check_mark:

Error tipográfico menor: supertype's probablemente debería ser supertype 's

Programación orientada a objetos: utilice un IIFE para crear un módulo :

PR enviado: white_check_mark:

Error tipográfico menor: "Aquí hay un ejemplo de uso:" debería cambiarse a "Aquí hay un ejemplo de uso:"

Otra sugerencia general: creo que debemos cambiar los ejemplos para que los campistas no puedan simplemente copiar el ejemplo y cambiar 1 o 2 cosas para completar el desafío.

Los ejemplos deben mostrar el concepto, pero no utilizar propiedades o métodos que se utilizan en el desafío mismo. De esta manera, creo que la gente aprenderá más de cada desafío.

Deshazte de CSS personalizado para Bootstrap

El sábado 4 de febrero de 2017 a las 9:11 p.m., Samuel Plumppu [email protected]
escribió:

Otra sugerencia general: creo que debemos cambiar los ejemplos para
Los campistas no pueden simplemente copiar el ejemplo y cambiar 1-2 cosas para completar el
desafío.

Los ejemplos deben mostrar el concepto, pero no utilizar propiedades ni métodos.
que son utilizados por el desafío mismo. De esta manera, creo que la gente aprenderá
más de cada desafío.

-
Recibes esto porque estás suscrito a este hilo.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/freeCodeCamp/freeCodeCamp/issues/12966#issuecomment-277463832 ,
o silenciar el hilo
https://github.com/notifications/unsubscribe-auth/AX9USApjW3rwocbHWe2yoFLV0RegbkCCks5rZL9SgaJpZM4LxApU
.

@iansibindi Parece que estás suscrito a todos los mensajes de este repositorio. Para desactivarlo, visite https://github.com/freecodecamp/freecodecamp y haga clic en "Dejar de mirar" en la parte superior derecha.

¡Lo siento por los inconvenientes ocasionados!

@Greenheart Me resulta un poco difícil seguir cada uno de estos incluso con los enlaces; ¡creo que tal vez debería haber abierto un número adicional para cada uno! Quería agregar una lista de verificación a los comentarios originales también.

Comenzaré a hacer una revisión inicial de los RP, pero ¿cree que podría agregar un comentario a cada uno de los comentarios originales si tienen un RP abierto para que podamos rastrear qué problemas se han abordado?

@ no-stack-dub-sack Jaja Tengo que admitir que tampoco puedo seguirlo yo mismo, ¡seguí publicando! :sonreír:

Agregaré un gran "PR abierto" (con un enlace a él) al comienzo de cada comentario que sea WIP / arreglado.

@Greenheart Perfecto! ¡Gracias! He revisado los primeros RP

@ no-stack-dub-sack ¡Muy bien, todavía quedan algunas cosas por hacer aquí, pero las resolví hoy!

Vaya, lo cerré de nuevo: riendo:

@Greenheart ¡Whoa! Un retroceso: ¿queda algo por hacer en este? ¡Se hicieron algunas mejoras importantes!

@ no-stack-dub-sack No lo sé: quedan algunas cosas por hacer de acuerdo con los comentarios anteriores, pero es posible que se hayan resuelto en otros lugares.

Creo que aún no está arreglado. Avísame si piensas lo contrario

Buen trabajo a todos. Estoy cerrando este problema y podemos reabrir problemas más específicos a medida que surjan.

¿Fue útil esta página
0 / 5 - 0 calificaciones