Git Product home page Git Product logo

not-awesome-es6-classes's Introduction

Not Awesome: ES6 Classes

A curated list of resources on why ES6 (aka ES2015) classes are NOT awesome

Reverse-inspired by all of the awesome lists on GitHub, like Awesome, Awesome Awesomeness, Awesome JavaScript, Awesome React, Awesome Cycle.js, Awesome Go, Awesome Elixir, Awesome Elm, etc.

Table of Contents

Introduction

While ES6 brings several useful and syntactically pleasing new features to JavaScript, there are many people in the JS community who feel that adding class syntax to the language was a mistake. I share this sentiment, but I have encountered quite a few programmers in the wild who don't agree or simply don't seem to understand why some of us have this opinion. So, I wanted to create an online reference where people could come to learn specifically about this issue and why they might not actually need class syntax in JavaScript.

TL;DR

DISCLAIMER: This is an opinionated summary of the core points made throughout the linked content. I am only providing this as a convenience for people who requested it. If you're looking for technical depth, skip this section. Please, take the time to dive into the content before drawing any conclusions.

  • JavaScript is a class-free, object-oriented, & functional programming language. It eschews classical inheritance in favor of prototypal inheritance. Although it is possible to emulate classical inheritance patterns in JS, classical inheritance is not built directly into the language, and many people believe prototypal inheritance to be a more flexible and freeing paradigm due to its less rigid nature. For more, first, read this. Then, read this.
  • The ES6 class syntax, constructors, the new keyword, etc. are ideas taken from the classical inheritance model to make programmers coming from languages like C++, Java, C#, etc. more comfortable and do not really belong in JavaScript. ES6 class syntax is essentially syntactic sugar that will end up obfuscating the true nature of JavaScript and confusing the next generation of programmers learning it.
  • While prototypal inheritance is very powerful in its own right, it is important to know that there is a growing movement among developers, both within and outside of the JS community (Ex: Composition in Golang), to shift away from inheritance in favor of object composition.
  • Whether you choose to use prototypal inheritance, composition, or some combination of the two, you should consider using factory functions, object literals, prototypes, Object.create(), Object.assign(), etc. while avoiding ES6 classes, constructors, and the new keyword altogether.

If a feature is sometimes dangerous, and there is a better option, then always use the better option. — Douglas Crockford

Reading

Articles & Blog Posts

Books

Videos

ES6 Classes in React

A Reasonable, Limited Approach to Using ES6 Class Syntax in React

Dan Abramov (creator of react-hot-loader, react-dnd, redux, and redux-devtools) has written an article on how to approach the use of ES6 classes in React in a limited & controlled way:

How to Use Classes and Sleep at Night

I'm not convinced that using ES6 class syntax in this fashion is the best long term solution for React, and you should be aware of the alternatives: React.createClass(), react-stamp, and pure (stateless) functions. However, Dan has established a solid, reasonable set of guidelines to follow in the meantime. So, if you must use ES6 classes in React, please follow his lead:

Key Points

  • Resist making classes your public API.
  • Don’t inherit more than once.
  • Don’t expect people to use your classes.
  • Learn functional programming.

Recommendations

  • You can use class in your JS if you don’t inherit twice and don’t use super.
  • Prefer to write React components as pure functions when possible.
  • Use ES6 classes for components if you need the state or lifecycle hooks.
  • In this case, you may only extend React.Component directly.
  • Give your feedback to the React team on the functional state proposals.

With that said, we should think about why needing to use class and extends in such a limited fashion, to establish sane & maintainable practices for the specific purpose of creating a React Component (through 1-level deep inheritance), is necessary in the first place. It probably means that there should be a better solution and/or a better syntactical approach to solving this problem. I’d like to see a syntax focusing on what the conceptual thing actually is, i.e., a component, not a class… Why was createClass() not originally named createComponent()? Why do we think that classes are the right tool for modeling components in the first place?

Also, read Dan's previous article on composition:

Mixins Are Dead. Long Live Composition

Don't Want to Use ES6 Classes in React?

Currently, it is not all that practical to completely avoid using ES6 classes in React due to the fact that functional components lack the lifecycle methods of ES6 class components (or the deprecated createClass factory function). However, it is possible to avoid them by using Andrew Clark's recompose, a React utility belt for function components and higher-order components. Using recompose, you are able to use methods like componentDidMount, shouldComponentUpdate, etc. with functional components via the lifecycle helper utility. However, lifecycle currently uses React's createClass under the hood, and many of recompose's other API methods are implemented using classes... So, you will probably still be using them if you use recompose in your project, depending on the specific methods you are using. However, they will be abstracted away from the code you are writing, which you might still find nice enough to consider.

Alternatively, if you are not 100% married to React, look into Dominic Gannaway's Inferno, which Dominic describes as "an extremely fast, React-like JavaScript library for building modern user interfaces." Although Inferno offers ES6 class style components through the optional inferno-component package, many users find they don't need them, because the library gives functional components access to all of the important lifecycle events. Some members of the React team have suggested that React's functional components might one day receive a similar feature, but this is not a top priority for them at the moment. If you choose to check out Inferno but still want access to the wealth of 3rd party React components out there, look into inferno-compat, a module which provides a compatibility layer that makes React-based modules work with Inferno without any code changes.

Otherwise, if you are willing to abandon React compatibility & a React-like API altogether, look into snabbdom, a virtual DOM library focused on simplicity, modularity, & performance. Like Inferno, Snabbdom is extremely fast and features a powerful hooks API. Also, if you are a fan of JSX, you can keep using it via snabbdom-jsx. You may be surprised how similar what you can accomplish when using a minimal virtual DOM library is to when using a larger view library like React, especially if you are already heavily using a state container like Redux.

Addendum (About Functional Programming)

Since writing this not-awesome-list I've really jumped into learning functional programming core concepts/principles, and, honestly, I don't really use prototypal inheritance or object composition anymore either, because I really believe FP is the way to go. However, I do still think that if you're going to do OOP in JS, then using prototypes & the OLOO (Objects Linked to Other Objects) concept + object composition is a much better idea than emulating Java with class syntax, the constructor pattern, & inheritance. Embrace simple! OO composition is better than classical inheritance by a long shot, but functional composition is even better.

People You Should Follow

The People Who Initially Inspired Me to Create This Repo

Awesome Functional Programming in JavaScript People

not-awesome-es6-classes's People

Contributors

joshburgess avatar petsel avatar reggi avatar troutowicz avatar

Watchers

Ciro avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.