Thanks :-)
I've never used Object.create for inheritance (although I heard it was a favorite of Douglas Crockford's at some point). And the syntactic sugar of es2015 classes is so appealing I never wrote constructor functions on a regular basis.
What's so conceptually difficult about es2015 classes that confuses people? They always felt intuitive to me. A bit restrictive perhaps, because you don't have private methods, or instance properties, and if you want to call super in a method you have to do it before anything else, but other than that — nothing especially confusing.
1) Prototypes with constructors using the "new" keyword (ES3+):
2) Plain prototypes with Object.create (ES5+): 3) Classes (ES2015+): Note how all three examples do (roughly) the same thing but in slightly different ways.Inheritance in #1 is a bit awkward (which is why before ES2015 there were myriads of different inheritance libraries).
In #2 it's fairly straightforward but type checks are unintuitive because there really aren't any types involved (instanceof requires a constructor).
In #3 both inheritance and type checks are fairly straightforward but it also uses more abstractions, which can make it more difficult to understand conceptually (especially when coming from a language like Java or C# which is syntactically similar).
IMO #1 is the worst of both worlds because the behaviour of the "new" keyword and the special "prototype" property are difficult to understand and the constructor looks like a regular function but expects to be called in a special way (using the "new" keyword) and will break in unexpected ways if called as a normal function:
> TypeError: Cannot set property 'name' of undefined
(or worse: outside strict mode it might not fail and actually try to write to the global scope -- so remember to always "use strict")
While the value of a class is also a constructor function, calling it without "new" will break with a distinct error that makes the mistake obvious and easy to understand:
> TypeError: Class constructor Qux cannot be invoked without 'new'