>
You can call a function with a different `this` value.To understand what that means, you need to understand what `this` is in Javascript -- that classes don't actually bind methods to an instance. So we have this idea of methods from other languages that turn out to be kind of the wrong way of thinking about things.
From `this`, the obvious next question is, "so what's the difference between adding a method to a class and just attaching it to an object?" And it turns out that practically, the difference is very small -- and in fact it's very easy for us to remove or add methods to a class that look and act very similarly to the methods in a class descriptor. So what we're calling a "class" is no longer a descriptor or a set of laws about what an instance is and what it can do, it's just a blueprint of how to build an instance at runtime.
We haven't gotten rid of classes yet, but we're already working with something that feels foreign to a number of programmers coming out of traditional OOP languages. `this` means that what a traditional OOP programmer from Java thinks of as a "method" doesn't exist. It means that the context of a function is determined at runtime, not at compile time.
You don't need to use the word "prototype" to talk about that, but it's what I would call very prototype-ish behavior. Arguably, by the time someone understands `this`, they've already learned about half of what they need to know to grok prototypes anyway -- all that's left is to tell them that if a property isn't found on an object, there's a special property JS will traverse to look for it elsewhere. But sure, we can delay talking about that for right now.
> A constructor can override its return value and return something else besides the new instance of its class.
Constructors complicate things more. We already know from above that a class isn't really a descriptor of what an object can do, instead we're thinking about it like a blueprint that tells us how to create an object at runtime (this is also incorrect, but we're sticking with that definition because we don't want to use the word "prototype"). Now we find out we can override the return value of a constructor. The obvious question a good student will ask is, "why? What use-case is there for treating a constructor function like a normal function?"
Again, we don't have to jump to prototype from here, but we do kind of need to explain that the `new` keyword is actually doing most of the work when we build a class, and the reason we can do weird things with a constructor is because a constructor is just another function. But we'll avoid prototype by saying that `new` just makes an instance of a class, and that behavior can be overridden by returning another object from the constructor that `new` invokes.
And when the student figures out that they can call `new` on an anonymous function without returning anything and it still creates an object, we can delay talking about prototype even farther, because we'll just lie and say that pure functions are a shorthand for making classes that are only a constructor.
But increasingly the question becomes, why wouldn't we talk about prototype now? Ostensibly, the point of classes is that it hides all the weirdness of the prototype system. In my experience, people struggle with prototypes because they're not Java. But JS classes also aren't Java, or at least they stop being Java as soon as you do anything even mildly interesting with them. So if people who learn classes in depth still have to grapple with the fact that class definitions are constructed at runtime, and that instance methods can be modified after they're created, and that methods aren't inherently bound to instances at all, what have we gained?