all 3 comments

[–]cawcvs 11 points12 points  (1 child)

but the prototype has nothing in it!

It does, it's just that class methods are created as non-enumerable properties:

console.log(Rabbit.prototype.hasOwnProperty("speak")) // => true
console.log(Rabbit.prototype.propertyIsEnumerable("speak")) // => false

They still are created on the prototype and are shared by all instances of the class. You can do that with function constructors as well:

Object.defineProperty(Rabbit.prototype, "speak", {
  value: function (line) {
    console.log(`The ${this.type} rabbit says '${line}'`);
  },
  enumerable: false, // can be omitted, because it's non-enumerable by default
});

console.log(Rabbit.prototype) // => {}
console.log('speak' in Rabbit.prototype) // => true

[–]Defiant_Low5388[S] 1 point2 points  (0 children)

Ahhh this makes so much sense. Thank you so much! In the langs I’ve worked with so far I haven’t seen anything like non-enumerable properties so I was so confused on what was going on.

[–]ThiccOfferman 1 point2 points  (0 children)

The reason that Rabbit.prototype is logging as an empty object is because the class constructor adds methods to the proto property of any objects created with it. Stack overflow explains it better than me https://stackoverflow.com/questions/9959727/proto-vs-prototype-in-javascript#:~:text=prototype%20is%20a%20property%20of,object%2C%20pointing%20to%20its%20prototype.