
Refactoring Legacy JavaScript Code to Use Classes - breck
https://arxiv.org/abs/1703.01690
======
pg_bot
While I'm a huge fan of what ES2015 has brought to JavaScript, the "class"
keyword was a huge mistake. There are no classes in Javascript, there are only
objects. By embracing prototypal inheritance you will write cleaner code with
fewer errors.

~~~
namelezz
Can you give an example of errors introduced by using "class"?

~~~
JSDave
There's a lot of reasons against classes in JS. This list has a lot of
articles. [https://github.com/joshburgess/not-awesome-
es6-classes](https://github.com/joshburgess/not-awesome-es6-classes) A common
point seems to be against the brittleness caused by inheritance (including
prototypical) in general. Personally, I find that the tiny amount of
performance you give up by using factory and composition patterns is generally
worth not having to deal with binding the right context

~~~
chickenfries
Grand-parent comment asked for an example of an error introduced by using
class that would've been avoided with prototype inheritance, and you respond
with an "awesome" "curated" list of opinion pieces and conference talks by
famous devs and rockstars...

This is what's wrong with the JS community and why everything is so hype
driven... this list gives the impression that if you want to be a good JS
developer you should've even THINK about trying to use classes in your JS
because if you do then you don't truly "get" JS.

Think for yourself and decide if classes will improve your code in the way you
plan to use it. Classes have hugely improved my company's JavaScript, it works
well considering our developers understand OOP much better than they do
functional programming, which I think is pretty common.

We don't rely on inheritance, we reuse by composition (which is just as easy
to do with class as it is to do with protypes).

Classes are fine! Use them if you want to! Don't use them if your existing
code relies heavily on prototypal inheritance, but if you just wanna wrap some
methods around some internal state and you like the way the class syntax looks
compared to the prototype syntax don't let some think piece on medium try to
convince you that classes are bad.

EDIT: sorry to go off on a slightly OT rant on your comment... I just got
frustrated by the link you posted.

~~~
JSDave
That list is actually making fun of what you're describing in the JS
community. "Not Awesome" is a play on the "Awesome" lists like this
[[https://github.com/sindresorhus/awesome](https://github.com/sindresorhus/awesome)]

JS classes were extremely hyped up a year ago. Taking a stance against classes
was going very hard against the hype.

How well your devs understand the code is the only real metric. If you
understand OOP better, stick with it!

~~~
chickenfries
Huh, I must have missed the "classes are great" wave. I only remember the
"classes are bad" FUD represented by this list... HN is my main connection to
the hype train these days since I quit Twitter.

> How well your devs understand the code is the only real metric. If you
> understand OOP better, stick with it!

Agreed.

------
vjeux
If you are interested in this sort of work, we've been doing this for years at
Facebook and are publishing all our "codemods" in a repo:

\- JS: [https://github.com/cpojer/js-
codemod/tree/master/transforms](https://github.com/cpojer/js-
codemod/tree/master/transforms)

\- React: [https://github.com/reactjs/react-
codemod/tree/master/transfo...](https://github.com/reactjs/react-
codemod/tree/master/transforms)

We built and ran the codemod they talk about in this paper many years ago
across thousands of files. Unfortunately, we didn't have the infra open
sourced so the actual codemod didn't get open sourced.

~~~
cpojer
Indeed. I also spoke about this topic a lot:
[https://www.youtube.com/watch?v=d0pOgY8__JM](https://www.youtube.com/watch?v=d0pOgY8__JM)

------
daliwali
All of a sudden, perfectly working JS becomes "legacy" code due to the
introduction of a new feature in the spec. There's that saying, only the
software industry is more driven by trends than the fashion industry.

~~~
pitaj
This new feature allows you to make code more structured and maintainable. Of
course people are going to use it, and even change old code to use it.
`Array.forEach` and `Object.keys` were new features in ES5, should people just
leave their old `for` loops anyways? Refactoring old code is a good way to
keep your codebase consistent and maintainable.

~~~
daliwali
Hahaha, no. Every time the argument for "maintainability", or some other
subjective quality like "readability" is mentioned, another question must be
answered "to who?" The class keyword was added a few years too late to
accomodate the horde of desktop Java/.NET developers moving to the web
platform, who simply did not grok prototypal inheritance. Now they don't have
to.

>`Array.forEach` and `Object.keys` were new features in ES5, should people
just leave their old `for` loops anyways?

Emphatic yes, people should keep using their "old" loops. They do less and are
much faster.

------
scj
Given the topic was Javascript class-based programming in-the-large, I was
surprised this paper didn't mention the use of closures as a means to
implement encapsulation. Especially during the part about supporting static
properties shared between objects. One method to implement something like a
static property is to declare a variable (and optional getter/setter) in an
anonymous function that also contains the "class" definition.

The most surprising part is the title "... The Good, The Bad, and The Ugly"
given that Crockford's similarly named Javascript book brings up relevant
cases that I didn't see addressed.

------
baron816
This seems like a big mistake to me.

------
josteink
Classes are a nice tool to cleaner code if used correctly.

People are using them all over the JS-verse already, just manually and verbose
using inconsistent and incompatible implementations.

I fail to see why everyone here are so negative to actually standardizing
something everyone is already doing anyway.

Someone please enlighten me?

~~~
chickenfries
I think some JavaScript developers feel a sort of stockholm-syndrome
attachment to the features of JavaScript that make it unique.

We've been hearing for so many years that our bread and butter language was
terrible, so we told ourselves that other people just hadn't spent the time to
take advantage of the less commonly understood features of JS (not unique,
just lest common among popular industry languages like python, java, etc).
This leads to people claiming that prototypal inheritance always better than
classical inheritance (everyone else who uses classes are just misguided), or
that JavaScript is "functional" just because it has first class functions.

I used to feel this way about classes too. Now that I've started using them at
work I feel like there is a great desire to justify the amount of time that
has been spent hacking on prototypal inheritance to behave like classes.

~~~
Raphmedia
When the language featured prototypal inheritance as its main workhorse, it
was stupid to try and hack classes together simply because you couldn't wrap
your head around prototypal inheritance. That's like if I started to use
python and instead of using classes I hacked together a prototypal inheritance
system because classes were too outlandish for me.

Now that the newest versions of ES brings classes out of the box the point is
moot. Use the one you are comfortable with or the one your team agreed with.

~~~
chickenfries
I agree, in the past, it would've been better for everyone to adopt prototypal
inheritance instead of the dozens of half-baked class implementations we have
now, but the fact that people tried to hack classes into JS shows that
prototypal inheritance was the wrong design choice in the first place.
JavaScript developers (in the general, not just the ones on HN) wanted
classes.

~~~
Raphmedia
I think it really depends in what order you learn things.

If you start your career with web technologies and your first programming
language is JS, you have no issues with prototypal inheritance.

The problem is when have developers that are used to classical inheritance and
expect them to do a bit of JS on the side. Of course they wouldn't want to
learn a new mindset simply to "add some blink on the website".

~~~
voyou
TBH, I think the main difficulty is caused by people claiming there's some
huge difference between prototype based and class based OO. There isn't,
really (at least, not if you're comparing JavaScript and other widely used
dynamic OO languages; prototype-based languages which emphasise copying,
rather than delegation, are a bit more different).

In both cases, you can share behaviour between objects by putting that
behaviour in another object and attaching it in a special way to the objects
that should have similar behaviour - in JavaScript it's called __proto__, in
Python it's called __class__, etc. Python (and Ruby, Smalltalk, and others)
introduce an additional "meta" level of shared behaviour between all these
class objects, whereas JavaScript (and Self) don't, but that's a comparatively
technical implementation detail. Most languages other than JavaScript are
include slightly more language-level support for one particular pattern of
using this shared behaviour, which gives users of these languages a strong
hint as to how to use these capabilities.

The addition of a class keyword to JavaScript is good because it emphasises
what JavaScript shares with other dynamic OO languages.

~~~
chickenfries
Exactly. I don't get what secret superpowers I'm supposed to be gaining by
using prototype OO over classes. One of them is just more familiar to the vast
majority of programmers.

------
thegigaraptor
People need to take the time to learn JS instead of forcing their
understanding of programming upon it.

------
jorgenhorstink
Is my understanding of ES6 classes wrong, or is the first migration rule in
paragraph 3.1 missing the static keyword?

I'd think it should be:

    
    
      // ES5
      C.m3 = function(p3) { B4; }
      // ES6
      class C {
        ...
        static m3(p3) { B4; }
      }

~~~
pitaj
You're correct. Appears to be a typo.

------
grabcocque
I remember that when classes were proposed (in the defunct ES4 and again for
ES6) much of the opposition was of this changing the semantics of ES from
using prototype chains to classical inheritance, which was viewed as a step
backwards.

On the contrary though, since classes are carefully designed to be just
syntactic sugar around prototypes, it should be easy to migrate, right?

Well no, because the one thing that became obvious was that, since there were
no standards, and no clearly and obviously idiomatic way to do prototype
chains, nobody was doing them in a correct, consistent way.

So trying auto-migrate is almost certainly doomed except in trivial cases,
because as the article implies there's a high chance of it just being flat
wrong anyway.

------
draw_down
> _...although the language is prototype-based, the latest JavaScript
> standard, named ECMAScript 6 (ES6), provides native support for implementing
> classes..._

Ohhh boy. I predict trouble ahead.

