But does that mean JavaScript actually has classes? Plain and simple: No. ... the classes you have in other languages are not like the "classes" you're faking in JS.
At least a couple ECMAScript editors, Brian Terlson and Allen Wirfs-Brock, have implied or explicitly stated that the notion that JS classes are "fake" is incorrect.
Terlson explicitly said as much on reddit:
"it is not at all helpful for beginners to constantly be exposed to the notion that JS classes are "fake". They are not, they have real syntax and real semantics" (https://www.reddit.com/r/javascript/comments/4bmiqj/using_classes_in_javascript_es6_best_practice/d1avktu)
"There is no gold standard for "class". From a developer's perspective, a "class" is an OO encapsulation mechanism that involves creating methods, defining fields, and producing instances and has some sort of inheritance scheme. Making the definition of "class" more constrained than this is not only incorrect but also not a useful distinction to make at all." (https://www.reddit.com/r/javascript/comments/4bmiqj/using_classes_in_javascript_es6_best_practice/d1atm1a)
And Wirfs-Brock implied the same on twitter:
"What word do you use for âan open set of objects that share a common interface and implementationâ?" (https://twitter.com/awbjs/status/689506114807857152)
Wirfs-Brock also gave a talk showing how Smalltalk's class model and JavaScript's constructor pattern are "exactly the same, basically." (https://www.youtube.com/watch?v=EPHmm8JiGbg&t=37m28s)
Likewise, Python's and Ruby's class and inheritance models are strikingly similar as well. In both languages, a class is a memory consuming runtime object, and inheritance happens by delegation.
If we were to pick a definition of "class" that accommodates not just Java/C#/C++ but also Smalltalk/Python/Ruby, then it would probably have to be something very much like Wirfs-Brock's tweet: A class is a descriptor for an open set of objects that share a common interface and implementation.
And if we accept that as the definition of class, then we have to acknowledge that JS classes are not fake. JS has real classes just like Smalltalk/Python/Ruby have real classes.
I'm well aware of their opinions and I've debated both of those fine gentleman on many occasions. They're very smart and I respect them very much, but I think they're misguided on this point.
I stand by my assertion because the definition of "class" that most people have when they arrive at JS is shaped most strongly by Java and C++, mostly because academia still to this day prefers those languages in CS curriculums, just as it did 15-20 years ago when I went through it.
There's lots of opinions on what a class is or is not, and I've chosen mine and clearly stated it. I base that on both my own CS background, my own experience in C++ and Java, and the observation that many, many developers have taken similar paths to arrive at JS and found subsequent confusion (as evidenced by myriad posts on sites like SO).
The point I'm making is that the definition of class is less based on some academic principle and more on the common paths and experiences people have with it. I understand others have come through different paths, but this path I've taken and based my writings on is what works for me.
An alternative that might make everyone happy is rather than focus on real vs fake, you could instead say that JavaScript's classes are different than Java/C++ but similar to Python/Ruby. Then go on to explain the under-the-hood details. That way you can still acknowledge and address the common paths and experiences but without the controversy of treating any implementation that's different from Java as fake.
I can understand why "fake" ruffles feathers. I will perhaps think of a different term to create the contrast.
Just want to point out, for posterity sake, that nearly 100% of anyone I ever teach about "class" and "inheritance" find the notion of "retroactive inheritance" -- the idea that changing a "class" after instantiation has the retroactive effect on the instance -- strange and bizarre. The fact that you can do that in JS (and I guess in python/ruby, though I don't know those langs at all) is where the strong feelings of "that's not a class!" come from.
JS has a long rich history of being able to mutate objects and do all sorts of dynamic borrowing/sharing of method behavior. ES6 class came along and said "stop doing that" and "be static just like Java and C++ are".
I still feel a class that can create retroactive inheritance is a strange, unnatural -- ahem fake -- class. And the fact is, that's how JS's object system works. If you remove the ability to dynamically mutate objects, I think you remove one of the most important parts of the heart of JS.
...and I guess in python/ruby...
Yep. Couple minimal repl demos if you're curious.
Python: https://repl.it/CmeW/0
Ruby: https://repl.it/CmeX/0
If you remove the ability to dynamically mutate objects, I think you remove one of the most important parts of the heart of JS.
But... the class syntax _didn't_ remove that ability. Right? We can still monkey patch (dynamically mutate), or borrow methods from, a class's prototype same as we could a constructor function's prototype.
There's several caveats to that tho, like for instance the fact that super is statically bound and not dynamic like this. Eyes start glazing over in my workshops when I start explaining stuff like that. My conclusion is they want you to embrace static inheritance fully if you use the class keyword.
Weren't our super calls _always_ statically bound? Even long before ES6?
var P = {
foo: function() { console.log( "P.foo" ); }
}
var C = {
foo: function() {
// super();
P.foo.call(this);
}
}
// Link C to P for delegation
Object.setPrototypeOf( C, P );
var c1 = Object.create(C);
c1.foo(); // "P.foo"
var D = {
foo: function() { console.log( "D.foo" ); }
};
var E = {
foo: C.foo
};
// Link E to D for delegation
Object.setPrototypeOf( E, D );
E.foo(); // "P.foo"
Even in the pre-ES6 days, borrowing methods that make some kind of super call was still just as problematic.
@Jeff-Mott-OR:
With respect to your argument that YDKJS is wrong to claim that JavaScript only has âfake classes,â and that smart people disagree with the book, I wish to disagree that the book is wrong to make such an âopinionatedâ claim, and furthermore to argue that it is valuable to stake out such a contrarian position.
Let me start with this quote of yours
An alternative that might make everyone happy is...
Right there is the issue with this thread. A book is not an exercise in making everybody happy. Down that road lies pablum, everything boiled and blended until it is bland and ultimately, neither appetizing nor informative.
There are hundreds or even thousands of books about a popular language like JavaScript. Every book (or series of books) must stake out some kind of unique territory to be worth investing the time to read it, much less money to buy it.
By the nature of the beast, the more unique it is, the greater the likelihood that it will differ in some substantial way from the perspective of some other author or person. So the fact that a book is not all things to all people is not a disadvantage, itâs practically a requirement to be worth reading.
Given this idea of a book needing to be original and therefore to stake out a unique position on worthwhile matters (which you may choose to reject), the question becomes whether the way in which it stakes out its own territory is a benefit or a hazard.
I happen to write about âclassesâ in a way that is very different than YDKJS, but at the same time, I also think that the take-no-prisoners JavaScript-does-not have-real-classes perspective has enough meat on the bones to be informative.
If you reject it outright and say, âWell, these smart people disagree,â I think you are the poorer for that. I suggest you are better off saying, âWell, that is interesting, this author rejects something that appears at first glance to be a central pillar of the way these smart people describe the language. Whatâs up with that?â
Honestly, I can make a number of arguments in favour of saying that JavaScript doesnât even fake classes, it doesnât have them at all, not real, not fake. I can argue that the JS approach of âThe word âclassâ means whatever anybody feels like it meansâ waters down the word âclassâ to be practically useless for thinking and reasoning.
But this is YDKJS, and it makes its own excellent arguments. What is good about this series of books is that it is _internally consistent_: Its arguments about classes fit neatly with its arguments about everything else, so in sum it presents a coherent and useful model for thinking about JavaScript and using JavaScript. One can read the books and still use âclassesâ whether fake or bullshit or watered-down, one just thinks of them in a different way.
Or one can move along and decide to embrace what JavaScript calls classes in its pop culture way, and think, âWell, JS has classes, but I learned a lot from taking the time to understand the YDKJS perspective.â
Either way, I believe that this series of books should stay the course on its opinions about classes. It is not an official reference book. It does not purport to present the OneTrueWay:tm: to write programs. It promises that there are things we dont know about JavaScript, and that it will tell us these things, and that when we have learned them, we will be better programmers.
I think this is true of the series in general, and I claim this is true of its opinionated statement that JavaScript has fake classes. Even if you move along and decide to believe something else, I claim that you learn something you didnât know by putting that disagreement aside and following YDKJSâs reasoning long enough to understand it.
Of course they're fake. The new operator has been in use to instantiate "classes". But new doesn't return a new instance of the class...it returns a reference! Classes, such as in Java, just hold a contract and when new is called on them, a brand new object is created, not a reference.
So basically, the one operator we have had for years to use Javascript "classes"--new-- is entirely fake and misleading.
Well... new _does_ create a new object... and all objects are held by reference. So I don't understand that line of reasoning at all. This object is not an instance of a class though. It's just linked to another object.
I never said it doesn't return a new object. I said it doesn't instantiate a new instance of the class. All of the "class" properties are really just a reference to the .prototype of the function.
Acceptable to say fakery but not fake?
C'mon folks ECMAScript is about functional programming and DOM manipulation.
MDN states: "JavaScript classes, introduced in ECMAScript 2015, are primarily syntactical sugar over JavaScript's existing prototype-based inheritance. The class syntax is not introducing a new object-oriented inheritance model to JavaScript. JavaScript classes provide a much simpler and clearer syntax to create objects and deal with inheritance."
Ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
Embrace the advantages of Functional Programming and reap the benefits. Hold on to OOP paradigms and miss the whole point. Chaining, streams, mapping, functors, monads and more await!
Most helpful comment
@Jeff-Mott-OR:
With respect to your argument that YDKJS is wrong to claim that JavaScript only has âfake classes,â and that smart people disagree with the book, I wish to disagree that the book is wrong to make such an âopinionatedâ claim, and furthermore to argue that it is valuable to stake out such a contrarian position.
Let me start with this quote of yours
Right there is the issue with this thread. A book is not an exercise in making everybody happy. Down that road lies pablum, everything boiled and blended until it is bland and ultimately, neither appetizing nor informative.
There are hundreds or even thousands of books about a popular language like JavaScript. Every book (or series of books) must stake out some kind of unique territory to be worth investing the time to read it, much less money to buy it.
By the nature of the beast, the more unique it is, the greater the likelihood that it will differ in some substantial way from the perspective of some other author or person. So the fact that a book is not all things to all people is not a disadvantage, itâs practically a requirement to be worth reading.
Given this idea of a book needing to be original and therefore to stake out a unique position on worthwhile matters (which you may choose to reject), the question becomes whether the way in which it stakes out its own territory is a benefit or a hazard.
I happen to write about âclassesâ in a way that is very different than YDKJS, but at the same time, I also think that the take-no-prisoners JavaScript-does-not have-real-classes perspective has enough meat on the bones to be informative.
If you reject it outright and say, âWell, these smart people disagree,â I think you are the poorer for that. I suggest you are better off saying, âWell, that is interesting, this author rejects something that appears at first glance to be a central pillar of the way these smart people describe the language. Whatâs up with that?â
Honestly, I can make a number of arguments in favour of saying that JavaScript doesnât even fake classes, it doesnât have them at all, not real, not fake. I can argue that the JS approach of âThe word âclassâ means whatever anybody feels like it meansâ waters down the word âclassâ to be practically useless for thinking and reasoning.
But this is YDKJS, and it makes its own excellent arguments. What is good about this series of books is that it is _internally consistent_: Its arguments about classes fit neatly with its arguments about everything else, so in sum it presents a coherent and useful model for thinking about JavaScript and using JavaScript. One can read the books and still use âclassesâ whether fake or bullshit or watered-down, one just thinks of them in a different way.
Or one can move along and decide to embrace what JavaScript calls classes in its pop culture way, and think, âWell, JS has classes, but I learned a lot from taking the time to understand the YDKJS perspective.â
Either way, I believe that this series of books should stay the course on its opinions about classes. It is not an official reference book. It does not purport to present the OneTrueWay:tm: to write programs. It promises that there are things we dont know about JavaScript, and that it will tell us these things, and that when we have learned them, we will be better programmers.
I think this is true of the series in general, and I claim this is true of its opinionated statement that JavaScript has fake classes. Even if you move along and decide to believe something else, I claim that you learn something you didnât know by putting that disagreement aside and following YDKJSâs reasoning long enough to understand it.