Почему при описании класса должно присутствовать и то, и другое?
С чего вы взяли? Может не быть ни того, ни другого.
Чем в классах JavaScript по функционалу различаются constructor и set?
Сеттеры отвечают за установку значения одного конкретного свойства; конструктор - за инициализацию объекта в целом.
И для чего нужно _dogName, если есть просто dogName?
Не может быть у объекта свойства (_dogName) и метода-сеттера (dogName) с одинаковым названием.
Приведённый вами пример можно упростить до такого и всё продолжит работать:
class Dog
{
constructor(dogName)
{
this.dogName = dogName;
}
}
let dog = new Dog("Rex");
console.log(dog.dogName);
Пока забудьте про геттеры и сеттеры - когда они вам понадобятся, вы сразу поймёте зачем они нужны. Сосредоточьтесь на конструкторах для начала.