
ES6 Classes - octosphere
https://www.javascriptjanuary.com/blog/es6-classes
======
ChrisSD
I think ES6 classes are the worst of all worlds. I know people from a Java
background really want classes in their Javascript but this is not that.

ES6 classes look like kind of sort of like a class but if you poke it at all
you see lots of sharp edges and weird behaviours that make no sense unless you
know what it's sugar for.

~~~
gedy
I think the point was to simplify the JS Prototype syntax to be more "normal-
looking" and less confusing to devs, not some rich OOP model compared to true
OOP languages.

~~~
dmitriid
> I think the point was to simplify the JS Prototype syntax to be more
> "normal-looking" and less confusing to devs

So they bolted on an incompatible thing that hides prototypes and is confusing
to devs:

    
    
       class C {
          y = 10;
    
          // this fine. "methods" defined as class properties
          // have access to proper `this` due to how class properties work
          // and scoping rules
          x = () => if(this.y > 10) this.y = 10; 
    
          constructor() {
              // if you don't bind `this`, `method()` will not have access
              // to `this`
              this.method = this.method.bind(this)
          }
    
          method() {
             // will refer to a wrong `y` if `this` isn't bound
             // in the constructor
             this.y++; 
          }
       }

~~~
oklahoma
You don't have to bind 'method' in the constructor to access 'y'. Just put
'this.y = 10;' in the constructor. Your example isn't legal JavaScript.

~~~
dmitriid
It's perfectly legal Javascript. Why would I put this.y = 10 in the
cinstructor? Do you even understand what this code does?

    
    
       const instance = new C();
       for(let i = 0; i < 20; i++) {
          instance.method();
       }
    
       instance.x()
    

If you don't bind `this` to `method` in the constructor, when you call
`instance.method()`, `this` will be whatever (window, IIRC).

Don't believe me? Try a more complex example like React's event handling with
`this.setState()`: [https://reactjs.org/docs/handling-
events.html](https://reactjs.org/docs/handling-events.html)

~~~
randallsquared
It is not legal JS as of January 2019.

> Why would I put this.y = 10 in the constructor?

Because that's how you initialize attributes of an object instance in JS, in
January 2019.

I don't believe this code does what you think it does. Even if your definition
of `x` generated an attribute of instances of C, using an arrow function would
defeat your apparent intention: arrow functions take their surrounding lexical
scope's `this`, which in this case is the class, not any instance you define
from the class.

> If you don't bind `this` to `method` in the constructor, when you call
> `instance.method()`, `this` will be whatever (window, IIRC).

Simply not the case, as another commenter has pointed out: `instance` in your
loop is definitely `method`'s `this`, and not `window`.

~~~
dmitriid
> It is not legal JS as of January 2019.

Ah, true. I keep forgetting class fields are not standardized yet since eve
ryone is using them anyway just because they are so damn handy.

> Even if your definition of `x` generated an attribute of instances of C,
> using an arrow function would defeat your apparent intention: arrow
> functions take their surrounding lexical scope's `this`, which in this case
> is the class, not any instance you define from the class.

For the current implementations of class fields this works. If they change
that behaviour, what good are classes?

~~~
randallsquared
> If they change [arrow functions taking `this` from lexical scope instead of
> caller], what good are classes?

Using an arrow function on a class field seems like a way to get static
methods that are still callable from the instance. But I'm not sure I have a
burning need for that at the moment...

------
randomfool
No-

    
    
        static isDog (animal) {
            return Object.getPrototypeOf(animal).constructor.name === this.name;
        }
    

Yes-

    
    
        static isDog (animal) {
            return animal instanceof Dog;
        }

~~~
chrismorgan
Or, if you want to check “is a Dog and not an instance of some subtype of it”:

    
    
        static isDog (animal) {
            return Object.getPrototypeOf(animal).constructor === this;
        }
    

Definitely no need for the `.name` check—that weakens it enormously,
especially in the presence of minification.

------
_31
I'm happy about the class syntax additions that came with ES6, especially the
method definitions. It's increased my productivity (and happiness) when
working with js.

~~~
nightski
My only complaint is having to manually bind methods in the constructor. I
understand why it's necessary but it is tedious. I suppose the answer is to
just use TypeScript but we are talking about ES6 here.

~~~
matthewmacleod
Have you looked at using arrow functions in class properties for this? They
have some issues, but avoid all the tedious manual binding.

Alternatively, the autobind decorator could help - though I’ve never used that
myself.

~~~
LiquidFlux
I've used Autobind a great deal as of recent with React classes, it's been
both pleasant to use and I've yet to experience any issues with it.

------
saagarjha
I’m quite unfamiliar with OOP in JavaScript, so I’d appreciate if someone
could chime in with how this differs from ES5: is this just syntactic sugar,
or is there a semantic change as well?

~~~
runarberg
From MDN[1]:

> JavaScript classes, introduced in ECMAScript 2015, are primarily syntactical
> sugar over JavaScript's existing prototype-based inheritance. The class
> syntax _does not_ introduce a new object-oriented inheritance model to
> JavaScript.

[1]: [https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Refe...](https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/Classes)

~~~
ronilan
Calling something “syntactical sugar” makes it sound unhealthy.

I found the ES6 classes to be very helpful in conceptualizing stuff. When I
started playing with them I’ve built myself a demo
[https://codepen.io/ronilan/pen/PObzew](https://codepen.io/ronilan/pen/PObzew)
as a clone of same done previously in Ruby. Then I found classes to be very
useful for bigger “vanilla” projects
([https://github.com/ronilan/BlockLike](https://github.com/ronilan/BlockLike))

I’d call them “syntactical vitamins”.

~~~
krapp
> Calling something “syntactical sugar” makes it sound unhealthy.

I would argue that, more often than not, it is, and it becomes less healthy
the more of it you have.

Javascript, for all its faults, is syntactically a simple language and it
should have been kept that way.

------
runarberg
Article from january last year. Should it be marked with (2018)?

------
11235813213455
I really dislike the formatting with a space between function name and
arguments

    
    
        function foo (a, b) {
    

compared to the more common:

    
    
        function foo(a, b) {

~~~
pagnol
For better or for worse this is part of the "Standard Style":
[https://www.npmjs.com/package/standard](https://www.npmjs.com/package/standard)

It always seemed like an odd choice to me that would make people less likely
to adopt it.

~~~
otras
Important emphasis on the quotation marks around the word standard. From the
readme:

> _But this isn 't a real web standard!_

> Of course it's not! The style laid out here is not affiliated with any
> official web standards groups, which is why this repo is called
> standard/standard and not ECMA/standard.

> The word "standard" has more meanings than just "web standard" :-)

I’m not a fan of the naming, but I could also be biased because I disagree
with some of the formatting rules.

