隆Te damos la bienvenida a este reto!

1

隆Bienvenido al mundo de JavaScript!

D铆a 1

2

Variables, funciones y sintaxis b谩sica

3

Tipos de datos

4

Playground - Retorna el tipo

5

Tipos de datos - pt 2

D铆a 2

6

Operadores

7

Hoisting y coerci贸n

8

Playground - Calcula la propina

9

Alcance de las variables

D铆a 3

10

Condicionales

11

Playground - Calcula a帽os bisiestos

12

Switch

13

Playground - Obten informaci贸n de mascotas seg煤n su tipo

14

Ciclos

15

Playground - Dibuja un triangulo

D铆a 4

16

Arrays

17

Playground - Encuentra al michi mas famoso

18

Objetos

19

Playground - Obten el promedio de los estudiantes

D铆a 5 - Checkpoint

20

Playground - encuentra el palindromo m谩s grande

D铆a 6

21

Reasignaci贸n y redeclaraci贸n

22

Modo estricto

D铆a 7

23

Debugging y manejo de errores

24

Programaci贸n funcional

Quiz: D铆a 7

D铆a 8

25

Closures

26

Playground - Crea una calculadora con closures

27

Higher order functions

28

Playground - Crea tu propio m茅todo map

D铆a 9

29

ECMAScript

30

TC39

Quiz: D铆a 9

D铆a 10 - Checkpoint

31

ES6

32

ES7

33

Playground - Task planner

D铆a 11

34

Asincronismo

35

Playground - Promesas

36

Manejando el asincronismo

37

Playground - Resuelve el callback hell usando promesas

38

Playground - Resuelve el callback hell usando async/await

D铆a 12

39

Arrays a profundidad

40

M茅todos de arrays: Every, Find y findIndex

41

Playground - V谩lida el formulario

D铆a 13

42

M茅todos de arrays: Includes, Join y concat

43

Playground - agrupa los productos

44

M茅todos de arrays: Flat y FlatMap

45

Playground - Encuentra la ubicaci贸n del valor buscado

D铆a 14

46

Mutable functions

47

Playground - Modifica una lista de compras

48

M茅todos de arrays: sort

49

Playground - Ordena los productos

D铆a 15 - Checkpoint

50

Playground - Sistema de reservaciones de un hotel

D铆a 16

51

Programaci贸n orientada a objetos en JavaScript

52

Objetos literales

53

Playground - Congela el objeto recursivamente

D铆a 17

54

Prototipos en JavaScript

55

Playground - Modifica el prototype de los arrays

56

Playground - Crea un auto usando clases

D铆a 18

57

Abstracci贸n en JavaScript

58

Playground - Sistema de carrito de compras

59

Encapsulamiento en JavaScript

60

Playground - Encapsula datos de los usuarios

D铆a 19

61

Herencia en JavaScript

62

Playground - Jerarqu铆a de animales

63

Polimorfismo en JavaScript

64

Playground - Sistema de pagos

D铆a 20 - Checkpoint

65

Playground - Agenda de vuelos

D铆a 21

66

Patrones de dise帽o

67

Sinlgeton y Factory pattern en JavaScript

68

Playground - Implementa singleton en un chat

D铆a 22

69

Adapter y Decorator pattern en JavaScript

70

Playground - Personaliza productos de una tienda

71

Builder y Protype pattern en JavaScript

72

Playground - Mejora el c贸digo usando builder pattern

D铆a 23

73

Facade y proxy pattern en JavaScript

74

Playground - Proxy en servicio de mensajer铆a

75

Chain of responsability y Observer pattern en JavaScript

76

Playground - Implementaci贸n de Observador en Newsletter

D铆a 24 - Checkpoint

77

Playground - Crea un task manager con patrones de dise帽o

D铆a 25

78

Estructuras de datos en JavaScript

79

Playground - Crea tu propia implementaci贸n de un array

80

Hash tables en JavaScript

81

Playground - Implementaci贸n de una HashTable para Contactos

D铆a 26

82

Set en JavaScript

83

Playground - Remueve duplicados de una lista

84

Maps en JavaScript

85

Playground - Crea un organizador de tareas

D铆a 27

86

Singly Linked List en JavaScript

87

Playground - Agrega m茅todos a la singly linked list

88

Playground - Implementaci贸n de una singly linked list

D铆a 28

89

Stacks en JavaScript

90

Playground - Crea un stack para una playlist

D铆a 29

91

Queues en JavaScript

92

Playground - Crea una cola de emails

D铆a 30

93

隆Lo lograste!

Live Class

94

30 d铆as de JS con Juan DC

95

30 d铆as de JS con Nicobytes

96

30 d铆as de JS con GNDX

97

30 d铆as de JS con LeoCode

98

30 d铆as de JS con Teffcode

99

Sesi贸n: Cierre de los 30 d铆as de JavaScript

No tienes acceso a esta clase

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

Playground - Crea una cola de emails

92/99

Aportes 25

Preguntas 0

Ordenar por:

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

馃洝锔忦煕★笍Escudo anti-spoilers馃洝锔忦煕★笍

Mi soluci贸n al reto:

import { Mail } from "./mail";

export class Queue {
  constructor() {
    this.first = null;
    this.last = null;
    this.length = 0;
  }

  enqueue(from, to, body, subject) {
    let newMail = new Mail(from, to, body, subject)
    if (this.length == 0) {
      this.first = newMail
      this.last = newMail
    } else {
      this.last.next = newMail
      this.last = newMail
    }
    this.length++
  }

  dequeue() {
    let r = this.first;
    if (this.first === this.last)
      this.last = null;
    this.first = this.first.next;
    this.length--
    delete r.next
    return r;
  }

  peek() {
    if (!this.first) return null
    return {
      from: this.first.from,
      to: this.first.to,
      body: this.first.body,
      subject: this.first.subject
    }
  }

  size() {
    return this.length
  }
}

馃洝锔忦煕★笍馃洝锔廍scudo anti spoilers馃洝锔忦煕★笍馃洝锔

Crea una cola de emails

Con ansias de que se venga el d铆a 30 y tambien 30 d铆as de Python 馃槏

Nunca pares de aprender 馃

import { Node } from "./node";

export class Playlist {
  constructor() {
    this.top = null;
    this.bottom = null;
    this.length = 0;
  }

  addSong(song) {
    const newSong = new Node(song);
    if (!this.top) {
      this.top = newSong
      this.bottom = newSong
      console.log(this);
    }
    else {
      newSong.next = this.top
      this.top = newSong
    }
    this.length++;
    return this
  }

  playSong() {
    if (!this.top) {
      throw new Error("No hay canciones en la playlist")
    }
    if (this.top == this.bottom) {
      this.bottom = null
    }
    const playedSong = this.top.value
    this.top = this.top.next
    this.length--;
    return playedSong
  }

  getPlaylist() {
    const playList = []
    if (!this.top) {
      return []
    }
    if (this.top) {
      playList.push(this.top.value)
      console.log(this.top.value)
      let currentSong = this.top
      while (currentSong.next) {
        playList.push(currentSong.next.value)
        currentSong = currentSong.next
      }
    }
    return playList
  }
}
![](https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExeWE2c2wxN2Z4MGtuYm4xYnd5Ynk5MThrY2FwZTA0c3EzN2xkODgxdCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/CS8Fgb5BAynaDGY1Me/giphy.gif) ![](https://static.platzi.com/media/user_upload/code-31dc197e-1064-4a3f-9ca9-a46c94dad51f.jpg)

Mi soluci贸n al problema.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

mail.js

export class Mail {
  constructor(from, to, body, subject) {
    this.from = from;
    this.to = to;
    this.body = body;
    this.subject = subject;
    this.next = null;
  }
}

exercise.js

import { Mail } from "./mail";

export class Queue {
  constructor() {
    this.first = null;
    this.last = null;
    this.length = 0;
  }

  enqueue(from, to, body, subject) {
    const newNode = new Mail(from, to, body, subject);
    if (this.length === 0) {
      this.first = newNode;
      this.last = newNode;
    } else {
      this.last.next = newNode;
      this.last = newNode;
    }
    this.length++;
  }

  dequeue() {
    if (this.length === 0) {
      throw new Error("La queue est谩 vac铆a");
    }

    const removedNode = this.first;
    if (this.first === this.last) {
      this.last = null;
    }

    this.first = this.first.next;
    this.length--;

    return {
      from: removedNode.from,
      to: removedNode.to,
      body: removedNode.body,
      subject: removedNode.subject,
    };
  }

  peek() {
    if (this.length === 0) {
      throw new Error("La queue est谩 vac铆a");
    }

    let currentNode = this.first;
    currentNode.next = null;

    return currentNode;
  }

  size() {
    return this.length;
  }
}

Creo que hay un error por parte de la eliminaci贸n del email ya que al desesctructurar el email mas viejo para quitar la clave que contiene al siguiente nodo/email retorna error, y funciona si simplemente se retorna el email mas antiguo junto con la clave de el email siguiente
Mi soluci贸n al reto:
.
.
.
.
.
.
.
.
.
.
.

import { Mail } from "./mail";

export class Queue {
  constructor() {
    this.first = null;
    this.last = null;
    this.length = 0;
  }

  enqueue(from, to, body, subject) {
    const newNode = new Mail(from, to, body, subject)
    if (this.length === 0) {
    this.last = newNode
    this.first = newNode
    }
    this.last.next = newNode
    this.last = newNode
    return this.length++
  }

  dequeue() {
    if (!this.first) {
      throw new Error('No hay elementos en la cola')
    }
    if (this.first === this.last) {
      this.last = null
    }
    const deleteEmail = this.first
    this.first = this.first.next
    this.length--
    return deleteEmail
  }

  peek() {
    const oldEmail = this.first
    delete oldEmail.next
    return oldEmail
  }

  size() {
    return this.length
  }
}

Hola dejo mi soluci贸n:


















Exercise.js

import { Mail } from "./mail";

export class Queue {
  constructor() {
    this.first = null;
    this.last = null;
    this.length = 0;
  }

  enqueue(from, to, body, subject) {
    const newMail = new Mail(from, to, body, subject);
    if (this.isEmpty()) {
      this.first = newMail;
    } else {
      this.last.next = newMail;
    }
    this.last = newMail;
    this.length++;
  }

  dequeue() {
    if (this.isEmpty()) {
      throw new Error("La cola est谩 vac铆a");
    }
    const removedMail = this.first;
    if (this.length === 1) {
      this.first = null;
      this.last = null;
    } else {
      this.first = removedMail.next;
    }
    removedMail.next = null;
    this.length--;
    return removedMail;
  }

  peek() {
    if (this.isEmpty()) {
      throw new Error("La cola est谩 vac铆a");
    }
    return this.first;
  }

  isEmpty() {
    return this.length === 0;
  }

  size() {
    return this.length;
  }
}

馃挌Mi Soluci贸n馃挌

馃洝锔廍scudo Anti-Spoilers馃洝锔


##馃懢C贸digo馃懢

import { Mail } from "./mail";

export class Queue {
  constructor() {
    this.first = null;
    this.last = null;
    this.length = 0;
  }

  enqueue(from, to, body, subject) {
    const newMail = new Mail(from, to, body, subject)

    if (this.length == 0) {
      this.first = newMail
      this.last = newMail
    } else {
      this.last.next = newMail
      this.last = newMail
    }

    this.length++
  }

  dequeue() {
    if (this.length == 0)
      throw new Error("No hay m谩s mails")

    const mail = this.first
    this.first = this.first.next

    if (this.length-- == 1)
      this.last = null

    return mail
  }

  peek() {
    return this.first
  }

  size() {
    return this.length
  }
}


.
.
.
.
.
.

exercise.js

class Queue {
  constructor() {
    this.first = null;
    this.last = null;
    this.length = 0;
  }

  enqueue(from, to, body, subject) {
    const newMail = new Mail(from, to, body, subject);
    if (this.length === 0) {
      this.first = newMail;
      this.last = newMail;
    } else {
      this.last.next = newMail;
      this.last = newMail;
    }
    this.length++;
  }

  dequeue() {
    if (this.length === 0) throw new Error("La queue est谩 vac铆a");
    if (this.first === this.last) this.last = null;

    const deletedEmail = this.first;
    this.first = this.first.next;
    this.length--;

    return deletedEmail;
  }

  peek() {
    return this.first;
  }

  size() {
    return this.length;
  }
}

Mi solucion:
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

import { Mail } from "./mail";

export class Queue {
  constructor() {
    this.first = null;
    this.last = null;
    this.length = 0;
  }

  enqueue(from, to, body, subject) {
    // Tu c贸digo aqu铆 馃憟馃徎
    const newMail = new Mail(from, to, body, subject)
    // if (!this.first) Alternativa
    if (this.length === 0) {
      this.first = newMail;
      this.last = newMail;
    } else {
      this.last.next = newMail;
      this.last = newMail;
    }
    this.length++;
  }

  dequeue() {
    // Tu c贸digo aqu铆 馃憟馃徎
    if (this.length === 0)
      throw new Error('No hay email a revisar');
    const { from, to, body, subject } = this.first;
    if (this.first === this.last)
      this.last = null;
    this.first = this.first.next;
    this.length--;
    return { from, to, body, subject };
  }

  peek() {
    // Tu c贸digo aqu铆 馃憟馃徎
    if (this.length === 0)
      throw new Error('No hay email');
    return this.first;
  }

  size() {
    // Tu c贸digo aqu铆 馃憟馃徎
    return this.length;
  }
}

Soluci贸n

class Queue {
  constructor() {
    this.first = null;
    this.last = null;
    this.length = 0;
  }

  enqueue(from, to, body, subject) {
    // Tu c贸digo aqu铆 馃憟馃徎
    const newMail = new Mail(from, to, body, subject);
    if (this.length === 0) {
      this.first = newMail;
      this.last = newMail;
    } else {
      this.last.next = newMail;
      this.last = newMail;
    }

    this.length++;
    return this;
  }

  dequeue() {
    // Tu c贸digo aqu铆 馃憟馃徎

    const deletedMail = {
      from: this.first.from,
      to: this.first.to,
      body: this.first.body,
      subject: this.first.subject,
    };

    if (this.first === this.last) {
      this.first = null;
      this.last = null;
    } else {
      this.first = this.first.next;
    }

    this.length--;

    return deletedMail;
  }

  peek() {
    // Tu c贸digo aqu铆 馃憟馃徎
    return this.first ? this.first : null;
  }

  size() {
    // Tu c贸digo aqu铆 馃憟馃徎
    return this.length ? this.length : "Empty mailbox";
  }
}

馃洝锔忦煕★笍Escudo anti-spoilers馃洝锔忦煕★笍

Mi soluci贸n al reto

export class Mail {
  constructor(from, to, body, subject) {
    this.from = from;
    this.to = to;
    this.body = body;
    this.subject = subject;
    this.next = null;
  }

  json() {
    let { from, to, body, subject } = this;
    return { from, to, body, subject };
  }
}
export class Queue {
  constructor() {
    this.first = null;
    this.last = null;
    this.length = 0;
  }

  enqueue(from, to, body, subject) {
    const newMail = new Mail(from, to, body, subject);
    if (this.length === 0) {
      this.first = newMail;
      this.last = newMail;
    } else {
      this.last.next = newMail;
      this.last = newMail;
    }
    this.length++;
  }

  dequeue() {
    if (this.length === 0) {
      throw new Error("La queue est谩 vac铆a");
    }

    const removedMail = this.first;
    if (this.first === this.last) {
      this.last = null;
    }

    this.first = this.first.next;
    this.length--;
    return removedMail.json();
  }

  peek() {
    return this.first.json();
  }

  size() {
    return this.length;
  }
}

Aqu铆 mi soluci贸n:
.
.
.
.
.
.
.
.
.
.
.
.
exercise.js

import { Mail } from "./mail";

export class Queue {
  constructor() {
    this.first = null;
    this.last = null;
    this.length = 0;
  }

  enqueue(from, to, body, subject) {
    const newNode = new Mail(from, to, body, subject);
    if (this.length === 0) {
      this.first = newNode;
      this.last = newNode;
    } else {
      this.last.next = newNode;
      this.last = newNode;
    }
    this.length++;
  }

  dequeue() {
    if (this.length === 0) {
      throw new Error("No hay correos en cola")
    }

    let { from, to, body, subject } = this.first;
    let removedNode = { from, to, body, subject };
    if (this.first === this.last) {
      this.last = null;
    }

    // Reasignamos los valores
    this.first = this.first.next;
    // y reducimos la longitud
    this.length--;

    // Se retorna el valor del nodo removido
    return removedNode;
  }

  peek() {
    if (this.length === 0) {
      throw new Error("No hay correos en cola")
    }

    let { from, to, body, subject } = this.first;
    let firstNode = { from, to, body, subject };

    return firstNode;
  }

  size() {
    return this.length;
  }
}

MI SOLUCION 馃挭
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
class Mail

export class Mail {
  constructor(from, to, body, subject) {
    this.from = from;
    this.to = to;
    this.body = body;
    this.subject = subject;
    this.next = null;
  }
}

class Queue

import { Mail } from "./mail";

export class Queue {
  constructor() {
    this.first = null;
    this.last = null;
    this.length = 0;
  }

  enqueue(from, to, body, subject) {
    const newMail = new Mail(from, to, body, subject);
    if (this.length === 0) {
      this.first = newMail;
      this.last = newMail;
    } else {
      this.last.next = newMail;
      this.last = newMail;
    }
    this.length++;
  }

  dequeue() {
    if (this.length === 0) throw new Error("Los mails est谩n vac铆os");
    const removedMail = {
      from: this.first.from,
      to: this.first.to,
      body: this.first.body,
      subject: this.first.subject
    };
    if (this.first === this.last) this.last = null;
    this.first = this.first.next;
    this.length--;
    return removedMail;
  }

  peek() {
    return {
      from: this.first.from,
      to: this.first.to,
      body: this.first.body,
      subject: this.first.subject
    };
  }

  size() {
    return this.length;
  }
}

mail.js

export class Mail {
  constructor(from, to, body, subject) {
    this.from = from;
    this.to = to;
    this.body = body;
    this.subject = subject;
    this.next = null;
  }
  get() {
    return {from: this.from, to: this.to, body: this.body, subject: this.subject}
  }
}

exercise.js

import { Mail } from "./mail";

export class Queue {
  constructor() {
    this.first = null;
    this.last = null;
    this.length = 0;
  }

  enqueue(from, to, body, subject) {
    const node = new Mail(from, to, body, subject);
    if (this.length === 0) {
      this.first = node;
      this.last = node;
    } else {
      this.last.next = node;
      this.last = node;
    }
    this.length++;
  }

  dequeue() {
    if (this.length === 0) {
      throw new Error("La cola est谩 vac铆a");
    }
    const node = this.first;
    if (this.first === this.last) {
      this.last = null;
    }
    this.first = this.first.next;
    this.length--;
    return node.get();
  }

  peek() {
    if (this.length === 0) {
      throw new Error("La cola est谩 vac铆a");
    }
    return this.first.get();
  }

  size() {
    return this.length;
  }
}

estoy muy decepcionado con este ejercicio, porque el enunciado no corresponde con las pruebas unitarias, tuve que ver la soluci贸n para verificar, por favor, revisen para hacer los cambios correspondientes

Mi soluci贸n:
.
.
.
.
.
.
.
.
mail.js

export class Mail {
  constructor(from, to, body, subject) {
    this.from = from;
    this.to = to;
    this.body = body;
    this.subject = subject;
    this.next = null;
  }
}

exercise.js

import { Mail } from "./mail";

export class Queue {
  constructor() {
    this.first = null;
    this.last = null;
    this.length = 0;
  }

  enqueue(from, to, body, subject) {
    const newEmail = new Mail(from, to, body, subject)
    if (this.length === 0) {
      this.first = newEmail
      this.last = newEmail
    } else {
      this.last.next = newEmail
      this.last = newEmail
    }
    this.length++
  }

  dequeue() {
    if (this.length === 0) {
      throw new Error("La lista de correos est谩 vac铆a")
    }
    const {next, ...removedEmail} = this.first
    if (this.first === this.last) {
      this.last = null
    }
    this.first = this.first.next
    this.length--
    return removedEmail
  }

  peek() {
    const { next, ...firstEmail } = this.first
    return firstEmail
  }

  size() {
    return this.length
  }
}

Mi humilde solucion
.
.
.
.
.
.
.
.
.
.
.
.
.
.

import { Mail } from "./mail";

export class Queue {
  constructor() {
    this.first = null;
    this.last = null;
    this.length = 0;
  }

  enqueue(from, to, body, subject) {
    const newEmail = new Mail(from, to, body, subject)
    if (!this.length) {
      this.first = newEmail
      this.last = newEmail
    } else {
      this.last.next = newEmail
      this.last = newEmail
    }
    this.length++
  }

  dequeue() {
    if (!this.length) {
      throw new Error('La queue esta vacia')
    }
    let removedMail = this.first
    if (this.first === this.last) {
      this.last = null
    }
    this.first = this.first.next
    this.length--
    const { from, to, body, subject } = removedMail
    return { from, to, body, subject }
  }

  peek() {
    if (!this.first) return null
    const { from, to, body, subject } = this.first
    return { from, to, body, subject }
  }

  size() {
    return this.length
  }
}

Soluci贸n鈥 馃槃
.
.
.
.

.
.
exercise.js:

import { Mail } from "./mail";

export class Queue {
  constructor() {
    this.first = null;
    this.last = null;
    this.length = 0;
  }

  enqueue(from, to, body, subject) {
    let newMail = new Mail(from, to, body, subject);

    if (!this.first) {
      this.first = newMail;
      this.last = newMail;
    } else { 
      this.last.next = newMail;
      this.last = newMail;
    }

    this.length++;
  }

  dequeue() {
    if (!this.first) { 
      throw new Error("No hay correos por revisar");
    }

    let removedMail = this.first;

    if (this.first === this.last) { 
      this.last = null;
    }

    this.first = this.first.next;
    this.length--;
    return removedMail.toObject();
  }

  peek() {
    if (!this.first) { 
      return null;
    }

    return this.first.toObject();
  }

  size() {
    return this.length;
  }
}

.
mail.js:

export class Mail {
  constructor(from, to, body, subject) {
    this.from = from;
    this.to = to;
    this.body = body;
    this.subject = subject;
    this.next = null;
  }

  toObject() { 
    return {
      from: this.from,
      to: this.to,
      body: this.body,
      subject: this.subject
    }
  }
}
export class Queue {
  constructor() {
    this.first = null;
    this.last = null;
    this.length = 0;
  }

  enqueue(from, to, body, subject) {
    const newMail = new Mail(from, to, body, subject);
    if (!this.first) {
      this.first = newMail;
      this.last = newMail;
    } else {
      this.last.next = newMail;
      this.last = newMail;
    }
    this.length++;
  }

  dequeue() {
    if (!this.first) {
      throw new Error("No hay elementos en la Queue");
    }
    const removedMail = this.first;
    if (this.first === this.last) {
      this.last = null;
    }
    this.first = removedMail.next;
    this.length--;
    removedMail.next = null;
    return {
      from: removedMail.from,
      to: removedMail.to,
      body: removedMail.body,
      subject: removedMail.subject,
    };
  }

  peek() {
    if (!this.first) {
      return null;
    }
    return {
      from: this.first.from,
      to: this.first.to,
      body: this.first.body,
      subject: this.first.subject,
    };
  }

  size() {
    return this.length;
  }
}

.
.
.
.
.

import { Mail } from "./mail";

export class Queue {
  constructor() {
    this.items = [];
  }

  enqueue(from, to, body, subject) {
    const email = new Mail(from, to, body, subject);
    this.items.push(email);
  }

  dequeue() {
    if (this.isEmpty()) {
      throw new Error("No hay elementos en la Queue");
    }
    return this.items.shift().getData();
  }

  peek() {
    if (this.isEmpty()) {
      return null;
    }
    return this.items[0].getData();
  }

  size() {
    return this.items.length;
  }

  isEmpty() {
    return this.size() === 0;
  }
}
export class Mail {
  constructor(from, to, body, subject) {
    this.from = from;
    this.to = to;
    this.body = body;
    this.subject = subject;
    this.timestamp = new Date().getTime();
  }

  getData() {
    return {
      from: this.from,
      to: this.to,
      body: this.body,
      subject: this.subject,
    };
  }
}

Mi solucion
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.

class Mail {
  constructor(from, to, body, subject) {
    this.from = from;
    this.to = to;
    this.body = body;
    this.subject = subject;
    this.next = null;
  }
}

export class Queue {
  constructor() {
    this.first = null;
    this.last = null;
    this.length = 0;
  }

  enqueue(from, to, body, subject) {
    // Tu c贸digo aqu铆 馃憟馃徎
    const newNode = new Mail(from, to, body, subject);
    if (this.length === 0) {
      this.first = newNode;
      this.last = newNode;
    } else {
      this.last.next = newNode;
      this.last = newNode;
    }
    this.length++;
  }

  dequeue() {
    // Tu c贸digo aqu铆 馃憟馃徎
    if (this.length === 0) {
      throw new Error("La queue est谩 vac铆a");
    }

    const removedNode = this.first;
    if (this.first === this.last) {
      this.last = null;
    }

    this.first = this.first.next;
    this.length--;

    return {
      from: removedNode.from,
      to: removedNode.to,
      body: removedNode.body,
      subject: removedNode.subject
    };
  }

  peek() {
    // Tu c贸digo aqu铆 馃憟馃徎
    return {
      from: this.first.from,
      to: this.first.to,
      body: this.first.body,
      subject: this.first.subject
    };
  }

  size() {
    // Tu c贸digo aqu铆 馃憟馃徎
    return this.length;
  }
}

Mi soluci贸n:
.
.
.
.
.
.
.
.
.
.
.
.

import { Mail } from "./mail";

export class Queue {
  constructor() {
    this.first = null;
    this.last = null;
    this.length = 0;
  }

  enqueue(from, to, body, subject) {
    const newEmail = new Mail(from, to, body, subject);

    if (this.length === 0) {
      this.first = newEmail;
      this.last = newEmail;
    } else {
      this.last.next = newEmail;
      this.last = newEmail;
    }
    this.length++;    
  }

  dequeue() {
    if (this.length === 0) {
      throw new Error("La queue est谩 vac铆a");
    }
    const removedMail = this.first;
    if (this.first === this.last) {
      this.last = null;
    }

    this.first = this.first.next;
    this.length--;

    const {from, to, body, subject } = removedMail;
    return { from, to, body, subject };
  }

  peek() {
    const { from, to, body, subject } = this.first;
    return { from, to, body, subject };
  }

  size() {
    return this.length;
  }
}

Mi soluci贸n:
.
.
.
.
.
.
.
.
.
.

import { Mail } from "./mail";

export class Queue {
  constructor() {
    this.first = null;
    this.last = null;
    this.length = 0;
  }

  enqueue(from, to, body, subject) {
    const newNode = new Mail(from, to, body, subject);
    if (this.length === 0) {
      this.first = newNode;
      this.last = newNode;
    } else {
      this.last.next = newNode;
      this.last = newNode;
    }
    this.length++;
    return this;
  }

  dequeue() {
    if (this.length === 0) {
      throw new Error("La queue est谩 vac铆a");
    }

    const removedNode = this.first;

    if (this.first === this.last) {
      this.last = null;
    }

    this.first = this.first.next;
    
    this.length--;

    return {
      "from": removedNode.from,
      "to": removedNode.to,
      "body": removedNode.body,
      "subject": removedNode.subject,
    };
  }

  peek() {
    return this.first;
  }

  size() {
    return this.length;
  }
}

Pos mi aporte sobre el problema 馃槃. Camino anti spoiler basado en puntitos:

.
.
.
.
.
.
.
.
.
.
.

import { Mail } from "./mail";

export class Queue {
  constructor() {
    this.first = null;
    this.last = null;
    this.length = 0;
  }

  enqueue(from, to, body, subject) {
    const email = new Mail(from, to, body, subject)

    if (this.last) this.last.next = email
    this.last = email
    if (!this.first) this.first = email

    this.length++
  }

  dequeue() {
    const emailRemoved = this.first
    this.first = this.first.next
    this.length--
    return emailRemoved
  }

  peek() {
    return this.first
  }

  size() {
    return this.length
  }
}

**Hola dejo mi codigo con explicaciones de cada operador, explicado con detalles, ya que los uso para repasar conseptos basico de codigo **
Mi solucion es :
.
.
.
.

//mail.js
export class Mail {
  constructor(from, to, body, subject) {
    this.from = from;
    this.to = to;
    this.body = body;
    this.subject = subject;
    this.next = null;
  }
}

.

//exercise.js
import { Mail } from "./mail";

export class Queue {
  constructor() {
    this.first = null;
    this.last = null;
    this.length = 0;
  }

  enqueue(from, to, body, subject) {
//crea un nuevo objeto Mail con estos argumentos
    const newEmail = new Mail(from, to, body, subject)

    if (!this.length) {
//Si la cola est谩 vac铆a (es decir, su longitud es 0), el nuevo correo electr贸nico se convierte en el primer y 煤ltimo elemento de la cola.
      this.first = newEmail
      this.last = newEmail
    } else {
//De lo contrario, se agrega al final de la cola y se actualiza el puntero last
      this.last.next = newEmail
      this.last = newEmail
    }
//actualiso la longitud
    this.length++
  }

  dequeue() {
    if (!this.length) {
//Si la cola est谩 vac铆a (es decir, su longitud es 0), salta el error 
      throw new Error('La queue esta vacia')
    }
//guarda una referencia al primer elemento de la cola
    let removedMail = this.first
//Si el primer y el 煤ltimo elemento son iguales, solo borro el unico nodo y lo remplazo por null
    if (this.first === this.last) 
      this.last = null
    }
//el puntero se establece en el siguiente elemento en la cola y se reduce la longitud de la cola
    this.first = this.first.next
    this.length--
//destructuro para extraer las propiedades from, to, body y subject del "removeMail"
    const { from, to, body, subject } = removedMail
//las devuelve en un objeto
    return { from, to, body, subject }
  }

  peek() {
//verifica si el primer elemento de la cola es null. Si es as铆, devuelve null
    if (!this.first) return null
//destructuro para extraer las propiedades from, to, body y subject del "Del primer nodo de la cola "
    const { from, to, body, subject } = this.first
//las devuelve en un objeto.
    return { from, to, body, subject }
  }

  size() {
//me dice la longitud de la cola 
    return this.length
  }
}
undefined