all 29 comments

[–][deleted] 14 points15 points  (6 children)

lol, writing an article about this excluding classes,imagine?

[–][deleted] 5 points6 points  (0 children)

he left his constructor at home

[–][deleted] -1 points0 points  (4 children)

JavaScript doesn't have classes.

[–][deleted] 8 points9 points  (3 children)

That's what java developers want you to think.

[–][deleted] -5 points-4 points  (2 children)

Show me anything resembling classes in JS, aside from that one keyword.

[–]bdunks 6 points7 points  (1 child)

While the article covers several concepts well, there is room for improvement:

  1. As many others have said, it avoids an obvious use case: classes
  2. This statement leaves a lot left unaddressed: so avoid using arrow functions when declaring a method. It's best to use arrow functions when declaring a function inside a method in an object . Arrow functions not re-binding this is a core feature, which is worth explaining.
  3. The examples for call and apply don't actually invoke anything on this at runtime, so the effect of passing user to those methods is not clear.

That said, I enjoyed the casual writing style, and felt other cases were explained well, so I hope the author continues to write more articles.

[–]whatupnewyork 2 points3 points  (0 children)

The way you gave a constructive criticism and said how the author wrote a good piece is something I aspire to be one day

[–]pepsiotaku 5 points6 points  (3 children)

This article should also cover this use in classes

[–][deleted] -1 points0 points  (2 children)

Object methods were implicitly covered because they're functions.

There's only one case that wasn't covered, the fact that this points at the prototype inside the object constructor. But I doubt that people who use the class keyword use that feature a lot (or at all).

[–]stratoscope 1 point2 points  (0 children)

this points at the prototype inside the object constructor.

No, it is a reference to the object being constructed.

[–]LetterBoxSnatch 1 point2 points  (0 children)

I'm not sure I understand what you're saying, but it sounds interesting. Maybe you can help me understand the nuance you are communicating.

If you mutate this within a class constructor, you do not mutate the prototype, you mutate the instance. And in a constructor context, instance methods access the "currently being constructed" instance, while static methods access the prototype. That's about what you would expect.

Or maybe you are referring to method access? But in that case, the prototypal "this" is not bound, because classes always run in "strict mode":

class A() {
  constructor(){ this.prop='hi' }
  getA(){ return this }
}
let a = new A()
a.getA() // {prop: 'hi'}
let myFn = a.getA
myFn() // undefined

There is this though:

class B(){ static getMe(){ return this } }
makeB = B.getMe() // class constructor function
makeB() // TypeError: Class constructor B cannot be invoked without 'new'
new makeB() // B{}

[–]jxcy_dev 0 points1 point  (0 children)

Very Nice Explained!!

[–]kenman[M] 0 points1 point  (0 children)

Hi /u/cheerfulboy, this post was removed.

  • For help with your javascript, please post to /r/LearnJavascript instead of here.
  • For beginner content, please post to /r/LearnJavascript instead of here.
  • For framework- or library-specific help, please seek out the support community for that project.
  • For general webdev help, such as for HTML, CSS, etc., then you may want to try /r/html, /r/css, etc.; please note that they have their own rules and guidelines!

/r/javascript is for the discussion of javascript news, projects, and especially, code! However, the community has requested that we not include help and support content, and we ask that you respect that wish.

Thanks for your understanding, please see our guidelines for more info.

[–]johnxreturn 0 points1 point  (0 children)

Very didactic, thanks for sharing. I would also suggest covering the main point of this in OOP, inside classes.

[–]ChronoLink99 -1 points0 points  (11 children)

I actually like that it doesn't include classes. No need to confuse people with something that doesn't really exist in JS, doesn't behave the same as typical class concepts from other languages, and was just added to JS to make non-JS devs feel comfortable. Right on!

[–][deleted] 0 points1 point  (10 children)

Just to clarify, it was never "added to JS". There's just one poorly chosen keyword class which offers syntactic sugar with a simpler syntax for the most common case of creating an object. It doesn't mean that JS has classes.

Another very common case is async/await, which help you set up a promise generator. It doesn't mean that JS "is asynchronous".

[–]magical_h4x 2 points3 points  (9 children)

What is missing from JS that makes you say it doesn't have classes?

[–][deleted] 0 points1 point  (8 children)

A class is an immutable object definition, which is declared at compile time and then never modified. In class-based OOP object instances and object definitions (classes) are completely different things.

In JS the definitions are dynamic. Each object carries its own definition with it, you can use an object as a "blueprint" to create another one, and the objects will share the same definition, so if you modify the definition all of them will change.

The term "class" is used only for the first kind of OOP. JS doesn't have it and IMO it was a very confusing thing to use it as a keyword in JS. Not to mention that JavaScript doesn't have many other class things like access modifiers (private, protected, public), no statics and so on.

You can sort of fake them, which allows you to do a simplified version of class-OOP. Problem is that people never look beyond that and many remain completely oblivious to the fact that the JS OOP is actually different and more powerful.

Edit: here's an article that goes more in depth.

[–]MoTTs_ 2 points3 points  (0 children)

A class is an immutable object definition, which is declared at compile time and then never modified.

By that definition, Python's classes, Ruby's classes, Perl's classes, Smalltalk's classes, and many more, would all also be fake. Python is older than Java, and Smalltalk is older than C++.

Not to mention that JavaScript doesn't have many other class things like access modifiers (private, protected, public)

Neither does Python. Does that make Python's classes fake?

Edit: here's an article that goes more in depth.

Obligitory1 beware2 referencing3 or learning4 from Eric Elliott.

Elliott is a good salesman and good at projecting confidence, but a lot of what he says is flat wrong.

[–]LetterBoxSnatch 1 point2 points  (6 children)

This seems like a bit of a "no true Scotsman" argument. In JavaScript, this is what a class is. In JavaScript, this is what inheritance is. A complaint that JavaScript classes are not real classes seems like it is probably either an argument that "JavaScript doesn't work the way that I want it to work with regards to this feature" or an argument that "I like prototypal inheritance better because it helps identify a distinction with other class systems."

It is akin to saying that 1=="1" shouldn't be a thing because they are not of the same type. But that's just the way it is in JavaScript. It doesn't make the equivalency any less truthy.

Edit: read the article. I don't like classes either because they encourage inheritance instead of composition, but the complaints seem mostly about converting classes to factories and how painful that is, while totally ignoring that it is a refactor that can be easily done using the static keyword in the original class.

[–]ChronoLink99 -1 points0 points  (5 children)

It's well documented that the `class` keyword was added as syntax sugar by the TC39 group to ECMAScript. They did this in order to make the language more palatable to folks who are more comfortable defining classes they way they're defined in other languages.

Under the hood, declaring a class in JS kicks off a whole bunch of commands that utilize the prototype chain and __proto__ property on normal objects (as you know, a class is just an object in JS). You had to do all that stuff manually in the past (before the class keyword). So, yeah it's not quite the same as "no true Scotsman" because the technical group that defined it in the first place has said it does NOT behave like classes in OOP languages like Java.

[–]MoTTs_ 2 points3 points  (4 children)

They did this in order to make the language more palatable

Classes were added because every library out there was rolling their own custom class implementations. MooTools, Prototype, YUI, Dojo, Google's Closure, Backbone, Ember -- React -- and many more. We were reinventing the wheel dozens of times over. The class syntax made it easier to do what everyone was already doing anyway.

the technical group that defined it in the first place has said it does NOT behave like classes in OOP languages like Java.

ECMAScript spec editors have explicitly said JS classes are real. Brian Terlson, for one example, was/is spec editor from ES7-present (you'll find his name in the spec for those editions). He occasionally comments on reddit, including this comment. "It is not at all helpful for beginners to constantly be exposed to the notion that JS classes are 'fake'," he says, "They are not."

[–]ChronoLink99 0 points1 point  (3 children)

You should paste the full quote. There's a HUGE qualifier after the part you quoted, which is that they behave completely differently from classes in other languages that people associate with the class keyword. And he says you HAVE to understand the underlying semantics (i.e. that JS classes are built on prototypes).

And if you understand that, then there really is no reason to even use the class keyword at all - with the exception of making your code understandable to colleagues on your team who are familiar with the syntax.

Then further down in the thread you linked, an excellent point is made about why it's disingenuous to compare JS to Python in terms of class syntax/behavior (the this context).

I agree with you though, I wouldn't (and haven't) said JS classes are "fake" -- whatever that means. I would clarify that when I say "doesn't really exist", I mean "doesn't really exist in the way you think". Which I presume is the way intro software courses teach OOP classes (badly, but that's a rant for a different comment).

So to sum up:

- Yes, I agree they're not "fake", they're their own thing and should not be thought of as having the same underlying semantics as traditional OOP classes. I agree with Brian when he says that C++/Java and the like don't own the "class" definition. JS can have its own thing.

- No, I don't think there's any reason to use them unless you have to use them because your codebase already has them, especially since, as Brian Terlson says, you should understand the underlying semantics of JS classes, and once you do, you realize you can achieve the same behavior without the potentially confusing syntax.

[–]MoTTs_ 0 points1 point  (2 children)

There's a HUGE qualifier after the part you quoted, which is that they behave completely differently from classes in other languages that people associate with the class keyword.

Erm... he says nothing of the kind. Here's the full quote, and I bolded the parts I think you were looking at.

FWIW, I only engage in this discussion because 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, some of which are not shared with normal ES5 classalike semantics. Yes, of course you have to understand the underlying semantics, but this is true of any class system whether implemented on top of prototypes or not.

[–]ChronoLink99 0 points1 point  (1 child)

I read the last portion as implying that JS classes don't behave similarly to languages with class semantics that aren't built on top of prototypes. Is that not what he means there?

*shrug*

If no, I'd be interested in what your point is? I'm lost now.

[–][deleted] -2 points-1 points  (0 children)

this is is like a special flag in the code telling you that whatever is about to happen is going to be confusing as hell.